OSG Collision Detection

Source: Internet
Author: User

Http://bbs.vrchina.net/viewthread.php? Tid = 5196 & extra = Page % 3d1
OSG Collision Detection
Collision Detection involves various aspects of virtual simulation. Here I mainly introduce two applications:
1. Determine whether the camera is in conflict with the previous object.
The basic principles are as follows:
First, determine the old and new positions of the camera (the new position here is a new position where no obstacle is traveling in front), and then create a line segment using two points, then, determine whether the line segment has an intersection with the model. If there is an intersection, take the intersection as the new position (or take the point before the intersection as the new position ).


1. jpg(16.32 KB)

The two cameras roam Based on the terrain:
If no collision detection is performed, there may be two situations:
In the first case, the camera goes through the terrain:


2. jpg(11.76 KB)

In the second case, the camera is suspended.


3. jpg(9.14 KB)

In the first case, the camera will definitely collide with the terrain, but after the collision is detected, the camera will arrive at the position
If the height is above the terrain normal, another collision detection is required, as shown in:



4. jpg(9.3 KB)

Green represents the final position of the camera, thus ensuring that the height between the camera and the terrain is fixed.
In the second case, the collision cannot be detected in the first case of collision detection. Therefore, a collision detection is required,



5. jpg(10.57 KB)

Green represents the final position of the camera, thus ensuring that the height between the camera and the terrain is fixed.

Three important classes and functions

OSG: linesegmen
Class representing a line segment, including a start point and an end point
Osgutil: intersectvisiotr
Class that accepts line segments, used to identify the intersection with nodes.
The addlinesegment (line. Get () function is used to add a line segment to the list.
Osgutil: intersectvisitor: hitlist
You can obtain the specific point of intersection to calculate the distance.

Sample Code
Bool drivemanipulator: calcmovement ()
{
// If there are fewer than two events, an error is returned.
If (_ ga_t0.get () = NULL | _ ga_t1.get () = NULL) return false;
Double dt = _ ga_t0-> gettime ()-_ ga_t1-> gettime ();

If (dt <0.0f)
{
Policy (Info) <"Warning dt =" <dt <STD: Endl;
Dt = 0.0f;
}
Switch (_ speedmode)
{
Case (use_mouse_y_for_speed ):
{// Switch to up/down speed mode
Double DY = _ ga_t0-> getynormalized ();
_ Velocity = _ modelscale * 0.2f * dy;
Break;
}
Case (use_mouse_buttons_for_speed ):
{// Switch to the speed control mode with the mouse buttons
Unsigned int buttonmask = _ ga_t1-> getbuttonmask ();
If (buttonmask = guieventadapter: left_mouse_button)
{// Left-click Acceleration
_ Velocity + = DT * _ modelscale * 0.01;
}
Else if (buttonmask = guieventadapter: middle_mouse_button |
Buttonmask = (guieventadapter: left_mouse_button | guieventadapter: right_mouse_button ))
{// Click Stop
_ Velocity = 0.0;
}
Else if (buttonmask = guieventadapter: right_mouse_button)
{// Right-click to slow down
_ Velocity-= DT * _ modelscale * 0.01;
}
Break;
}
}

OSG: coordinateframe cf = getcoordinateframe (_ eye );
OSG: matrix rotation_matrix;
Rotation_matrix.makerotate (_ rotation );
OSG: vec3d up = OSG: vec3d (0.0, 1.0, 0.0) * rotation_matrix;
OSG: vec3d Lv = OSG: vec3d (0.0, 0.0,-1.0) * rotation_matrix;
OSG: vec3d SV = OSG: vec3d (1.0, 0.0, 0.0) * rotation_matrix;

// Rotate the camera
Double dx = _ ga_t0-> getxnormalized ();
Double yaw =-indegrees (dx * 501_f * DT );

# Ifdef keyboard_pitch
Double maid = 0.5;
If (_ pitchupkeypressed) _ pitch + = pitch_delta * DT;
If (_ pitchdownkeypressed) _ pitch-= pitch_delta * DT;
# Endif

# If defined (abosulte_pitch)
// Abosolute pitch
Double DY = _ ga_t0-> getynormalized ();
_ Pitch =-dy * 0.5;
# Elif defined (incremental_pitch)
// Incremental pitch
Double DY = _ ga_t0-> getynormalized ();
_ Pitch + = Dy * DT;
# Endif

OSG: quat yaw_rotation;
Yaw_rotation.makerotate (yaw, up );
_ Rotation * = yaw_rotation;
Rotation_matrix.makerotate (_ rotation );
SV = OSG: vec3d (1.0, 0.0, 0.0) * rotation_matrix;

If (FABS (_ velocity * DT)> 1e-8)
{
Double distancetomove = _ velocity * DT;
Double signedbuffer;
If (distancetomove >=0.0) signedbuffer = _ buffer;
Else signedbuffer =-_ buffer;
// Check whether there are obstacles in front
Osgutil: intersectvisitor IV;
Iv. settraversalmask (_ intersecttraversalmask );
OSG: ref_ptr <OSG: linesegment> segforward = new OSG: linesegment;
Segforward-> set (_ eye, _ eye + LV * (signedbuffer + distancetomove ));
Iv. addlinesegment (segforward. Get ());
_ Node-> Accept (IV );
// If a collision is detected
If (IV. Hits ())
{
Osgutil: intersectvisitor: hitlist & hitlist = IV. gethitlist (segforward. Get ());
If (! Hitlist. Empty ())
{
// Define y (Info) <"hit obstruction" <STD: Endl;
// Obtain the collision point
OSG: vec3d IP = hitlist. Front (). getworldintersectpoint ();
// Calculate the moving distance
Distancetomove = (IP-_ eye). Length ()-_ buffer;
_ Velocity = 0.0;
}
}

// Check whether the forward point is a fixed value higher than the terrain.
OSG: vec3d fp = _ eye + LV * distancetomove;
OSG: vec3d LFP = FP-up * _ height * 5;
Iv. Reset ();
OSG: ref_ptr <OSG: linesegment> segnormal = new OSG: linesegment;
Segnormal-> set (FP, LFP );
Iv. addlinesegment (segnormal. Get ());
_ Node-> Accept (IV );
// Perform the second Collision Detection
If (IV. Hits ())
{
Osgutil: intersectvisitor: hitlist & hitlist = IV. gethitlist (segnormal. Get ());
If (! Hitlist. Empty ())
{
// Y (Info) <"hit terrain OK" <STD: Endl;
OSG: vec3d IP = hitlist. Front (). getworldintersectpoint ();
OSG: vec3d Np = hitlist. Front (). getworldintersectnormal ();
If (up * NP> 0.0) up = NP;
Else up =-NP;
_ Eye = IP + up * _ height;
Lv = up ^ Sv;
Computeposition (_ eye, _ eye + LV, up );
Return true;
}
}

// If no collision is detected for the second time, perform the third collision detection.
OSG: vec3d dp = LFP;
DP-= getupvector (CF) * (2 * _ modelscale );
Iv. Reset ();
OSG: ref_ptr <OSG: linesegment> segfall = new OSG: linesegment;
Segfall-> set (LFP, DP );
Iv. addlinesegment (segfall. Get ());

_ Node-> Accept (IV );
If (IV. Hits ())
{
Osgutil: intersectvisitor: hitlist & hitlist = IV. gethitlist (segfall. Get ());
If (! Hitlist. Empty ())
{
// Reset y (Info) <"hit terrain on decent OK" <STD: Endl;
OSG: vec3d IP = hitlist. Front (). getworldintersectpoint ();
OSG: vec3d Np = hitlist. Front (). getworldintersectnormal ();
If (up * NP> 0.0) up = NP;
Else up =-NP;
_ Eye = IP + up * _ height;
Lv = up ^ Sv;
Computeposition (_ eye, _ eye + LV, up );
Return true;
}
}
LV * = (_ velocity * DT );
_ Eye + = lv;
}
Return true;
}

Summary
Collision Detection is very complex and involves knowledge about the surrounding body and intersection tests. It is only the simplest application of collision detection. The above thought is only a personal analysis, which has not been verified and details have not been taken into consideration. I hope you can give us guidance.

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.