3 * Copyright (c) 2007-2010 SlimDX Group
\r
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
\r
6 * of this software and associated documentation files (the "Software"), to deal
\r
7 * in the Software without restriction, including without limitation the rights
\r
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
\r
9 * copies of the Software, and to permit persons to whom the Software is
\r
10 * furnished to do so, subject to the following conditions:
\r
12 * The above copyright notice and this permission notice shall be included in
\r
13 * all copies or substantial portions of the Software.
\r
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\r
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
\r
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
\r
26 #include "BoundingBox.h"
\r
27 #include "BoundingSphere.h"
\r
31 using namespace System;
\r
32 using namespace System::Globalization;
\r
36 Ray::Ray( Vector3 position, Vector3 direction )
\r
38 Position = position;
\r
39 Direction = direction;
\r
42 bool Ray::Intersects( Ray ray, Plane plane, [Out] float% distance )
\r
44 ray.Direction.Normalize();
\r
45 float dotDirection = (plane.Normal.X * ray.Direction.X) + (plane.Normal.Y * ray.Direction.Y) + (plane.Normal.Z * ray.Direction.Z);
\r
47 if( Math::Abs( dotDirection ) < 0.000001f )
\r
53 float dotPosition = (plane.Normal.X * ray.Position.X) + (plane.Normal.Y * ray.Position.Y) + (plane.Normal.Z * ray.Position.Z);
\r
54 float num = ( -plane.D - dotPosition ) / dotDirection;
\r
58 if( num < -0.000001f )
\r
70 bool Ray::Intersects( Ray ray, Vector3 vertex1, Vector3 vertex2, Vector3 vertex3, [Out] float% distance )
\r
73 pin_ptr<float> pinnedDist = &distance;
\r
75 if( D3DXIntersectTri( reinterpret_cast<D3DXVECTOR3*>( &vertex1 ),
\r
76 reinterpret_cast<D3DXVECTOR3*>( &vertex2 ), reinterpret_cast<D3DXVECTOR3*>( &vertex3 ),
\r
77 reinterpret_cast<D3DXVECTOR3*>( &ray.Position ), reinterpret_cast<D3DXVECTOR3*>( &ray.Direction ),
\r
78 &u, &v, reinterpret_cast<FLOAT*>( pinnedDist ) ) )
\r
84 bool Ray::Intersects( Ray ray, BoundingBox box, [Out] float% distance )
\r
87 float maxValue = float::MaxValue;
\r
89 ray.Direction.Normalize();
\r
90 if( Math::Abs( ray.Direction.X ) < 0.0000001 )
\r
92 if( ray.Position.X < box.Minimum.X || ray.Position.X > box.Maximum.X )
\r
100 float inv = 1.0f / ray.Direction.X;
\r
101 float min = (box.Minimum.X - ray.Position.X) * inv;
\r
102 float max = (box.Maximum.X - ray.Position.X) * inv;
\r
111 d = Math::Max( min, d );
\r
112 maxValue = Math::Min( max, maxValue );
\r
121 if( Math::Abs( ray.Direction.Y ) < 0.0000001 )
\r
123 if( ray.Position.Y < box.Minimum.Y || ray.Position.Y > box.Maximum.Y )
\r
131 float inv = 1.0f / ray.Direction.Y;
\r
132 float min = (box.Minimum.Y - ray.Position.Y) * inv;
\r
133 float max = (box.Maximum.Y - ray.Position.Y) * inv;
\r
142 d = Math::Max( min, d );
\r
143 maxValue = Math::Min( max, maxValue );
\r
152 if( Math::Abs( ray.Direction.Z ) < 0.0000001 )
\r
154 if( ray.Position.Z < box.Minimum.Z || ray.Position.Z > box.Maximum.Z )
\r
162 float inv = 1.0f / ray.Direction.Z;
\r
163 float min = (box.Minimum.Z - ray.Position.Z) * inv;
\r
164 float max = (box.Maximum.Z - ray.Position.Z) * inv;
\r
173 d = Math::Max( min, d );
\r
174 maxValue = Math::Min( max, maxValue );
\r
187 bool Ray::Intersects( Ray ray, BoundingSphere sphere, [Out] float% distance )
\r
189 float x = sphere.Center.X - ray.Position.X;
\r
190 float y = sphere.Center.Y - ray.Position.Y;
\r
191 float z = sphere.Center.Z - ray.Position.Z;
\r
192 float pyth = (x * x) + (y * y) + (z * z);
\r
193 float rr = sphere.Radius * sphere.Radius;
\r
201 ray.Direction.Normalize();
\r
202 float dot = (x * ray.Direction.X) + (y * ray.Direction.Y) + (z * ray.Direction.Z);
\r
209 float temp = pyth - (dot * dot);
\r
216 distance = dot - static_cast<float>( Math::Sqrt( static_cast<double>( rr - temp ) ) );
\r
220 bool Ray::operator == ( Ray left, Ray right )
\r
222 return Ray::Equals( left, right );
\r
225 bool Ray::operator != ( Ray left, Ray right )
\r
227 return !Ray::Equals( left, right );
\r
230 String^ Ray::ToString()
\r
232 return String::Format( CultureInfo::CurrentCulture, "Position:{0} Direction:{1}", Position.ToString(), Direction.ToString() );
\r
235 int Ray::GetHashCode()
\r
237 return Position.GetHashCode() + Direction.GetHashCode();
\r
240 bool Ray::Equals( Object^ value )
\r
242 if( value == nullptr )
\r
245 if( value->GetType() != GetType() )
\r
248 return Equals( safe_cast<Ray>( value ) );
\r
251 bool Ray::Equals( Ray value )
\r
253 return ( Position == value.Position && Direction == value.Direction );
\r
256 bool Ray::Equals( Ray% value1, Ray% value2 )
\r
258 return ( value1.Position == value2.Position && value1.Direction == value2.Direction );
\r