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 "../SlimDXException.h"
\r
27 #include "../DataStream.h"
\r
29 #include "BoundingBox.h"
\r
30 #include "BoundingSphere.h"
\r
34 using namespace System;
\r
35 using namespace System::Globalization;
\r
39 BoundingBox::BoundingBox( Vector3 minimum, Vector3 maximum )
\r
45 array<Vector3>^ BoundingBox::GetCorners()
\r
47 array<Vector3>^ results = gcnew array<Vector3>( 8 );
\r
48 results[0] = Vector3(Minimum.X, Maximum.Y, Maximum.Z);
\r
49 results[1] = Vector3(Maximum.X, Maximum.Y, Maximum.Z);
\r
50 results[2] = Vector3(Maximum.X, Minimum.Y, Maximum.Z);
\r
51 results[3] = Vector3(Minimum.X, Minimum.Y, Maximum.Z);
\r
52 results[4] = Vector3(Minimum.X, Maximum.Y, Minimum.Z);
\r
53 results[5] = Vector3(Maximum.X, Maximum.Y, Minimum.Z);
\r
54 results[6] = Vector3(Maximum.X, Minimum.Y, Minimum.Z);
\r
55 results[7] = Vector3(Minimum.X, Minimum.Y, Minimum.Z);
\r
59 ContainmentType BoundingBox::Contains( BoundingBox box1, BoundingBox box2 )
\r
61 if( box1.Maximum.X < box2.Minimum.X || box1.Minimum.X > box2.Maximum.X )
\r
62 return ContainmentType::Disjoint;
\r
64 if( box1.Maximum.Y < box2.Minimum.Y || box1.Minimum.Y > box2.Maximum.Y )
\r
65 return ContainmentType::Disjoint;
\r
67 if( box1.Maximum.Z < box2.Minimum.Z || box1.Minimum.Z > box2.Maximum.Z )
\r
68 return ContainmentType::Disjoint;
\r
70 if( box1.Minimum.X <= box2.Minimum.X && box2.Maximum.X <= box1.Maximum.X && box1.Minimum.Y <= box2.Minimum.Y &&
\r
71 box2.Maximum.Y <= box1.Maximum.Y && box1.Minimum.Z <= box2.Minimum.Z && box2.Maximum.Z <= box1.Maximum.Z )
\r
72 return ContainmentType::Contains;
\r
74 return ContainmentType::Intersects;
\r
77 ContainmentType BoundingBox::Contains( BoundingBox box, BoundingSphere sphere )
\r
82 Vector3::Clamp( sphere.Center, box.Minimum, box.Maximum, clamped );
\r
84 float x = sphere.Center.X - clamped.X;
\r
85 float y = sphere.Center.Y - clamped.Y;
\r
86 float z = sphere.Center.Z - clamped.Z;
\r
88 dist = (x * x) + (y * y) + (z * z);
\r
89 float radius = sphere.Radius;
\r
91 if( dist > (radius * radius) )
\r
92 return ContainmentType::Disjoint;
\r
94 if( box.Minimum.X + radius <= sphere.Center.X && sphere.Center.X <= box.Maximum.X - radius &&
\r
95 box.Maximum.X - box.Minimum.X > radius && box.Minimum.Y + radius <= sphere.Center.Y &&
\r
96 sphere.Center.Y <= box.Maximum.Y - radius && box.Maximum.Y - box.Minimum.Y > radius &&
\r
97 box.Minimum.Z + radius <= sphere.Center.Z && sphere.Center.Z <= box.Maximum.Z - radius &&
\r
98 box.Maximum.X - box.Minimum.X > radius )
\r
99 return ContainmentType::Contains;
\r
101 return ContainmentType::Intersects;
\r
104 ContainmentType BoundingBox::Contains( BoundingBox box, Vector3 vector )
\r
106 if( box.Minimum.X <= vector.X && vector.X <= box.Maximum.X && box.Minimum.Y <= vector.Y &&
\r
107 vector.Y <= box.Maximum.Y && box.Minimum.Z <= vector.Z && vector.Z <= box.Maximum.Z )
\r
108 return ContainmentType::Contains;
\r
110 return ContainmentType::Disjoint;
\r
113 BoundingBox BoundingBox::FromPoints( array<Vector3>^ points )
\r
115 if( points == nullptr || points->Length <= 0 )
\r
116 throw gcnew ArgumentNullException( "points" );
\r
118 Vector3 min = Vector3( float::MaxValue );
\r
119 Vector3 max = Vector3( float::MinValue );
\r
121 for each( Vector3 vector in points )
\r
123 Vector3::Minimize( min, vector, min );
\r
124 Vector3::Maximize( max, vector, max );
\r
127 return BoundingBox( min, max );
\r
130 BoundingBox BoundingBox::FromPoints( DataStream^ points, int count, int stride )
\r
134 HRESULT hr = D3DXComputeBoundingBox( reinterpret_cast<D3DXVECTOR3*>( points->PositionPointer ), count, stride,
\r
135 reinterpret_cast<D3DXVECTOR3*>( &box.Minimum ), reinterpret_cast<D3DXVECTOR3*>( &box.Maximum ) );
\r
137 if( RECORD_SDX( hr ).IsFailure )
\r
138 return BoundingBox();
\r
143 BoundingBox BoundingBox::FromSphere( BoundingSphere sphere )
\r
146 box.Minimum = Vector3( sphere.Center.X - sphere.Radius, sphere.Center.Y - sphere.Radius, sphere.Center.Z - sphere.Radius );
\r
147 box.Maximum = Vector3( sphere.Center.X + sphere.Radius, sphere.Center.Y + sphere.Radius, sphere.Center.Z + sphere.Radius );
\r
151 BoundingBox BoundingBox::Merge( BoundingBox box1, BoundingBox box2 )
\r
154 Vector3::Minimize( box1.Minimum, box2.Minimum, box.Minimum );
\r
155 Vector3::Maximize( box1.Maximum, box2.Maximum, box.Maximum );
\r
159 bool BoundingBox::Intersects( BoundingBox box1, BoundingBox box2 )
\r
161 if ( box1.Maximum.X < box2.Minimum.X || box1.Minimum.X > box2.Maximum.X )
\r
164 if ( box1.Maximum.Y < box2.Minimum.Y || box1.Minimum.Y > box2.Maximum.Y )
\r
167 return ( box1.Maximum.Z >= box2.Minimum.Z && box1.Minimum.Z <= box2.Maximum.Z );
\r
170 bool BoundingBox::Intersects( BoundingBox box, BoundingSphere sphere )
\r
175 Vector3::Clamp( sphere.Center, box.Minimum, box.Maximum, clamped );
\r
177 float x = sphere.Center.X - clamped.X;
\r
178 float y = sphere.Center.Y - clamped.Y;
\r
179 float z = sphere.Center.Z - clamped.Z;
\r
181 dist = (x * x) + (y * y) + (z * z);
\r
183 return ( dist <= (sphere.Radius * sphere.Radius) );
\r
186 bool BoundingBox::Intersects( BoundingBox box, Ray ray, [Out] float% distance )
\r
188 return Ray::Intersects( ray, box, distance );
\r
191 PlaneIntersectionType BoundingBox::Intersects( BoundingBox box, Plane plane )
\r
193 return Plane::Intersects( plane, box );
\r
196 bool BoundingBox::operator == ( BoundingBox left, BoundingBox right )
\r
198 return BoundingBox::Equals( left, right );
\r
201 bool BoundingBox::operator != ( BoundingBox left, BoundingBox right )
\r
203 return !BoundingBox::Equals( left, right );
\r
206 String^ BoundingBox::ToString()
\r
208 return String::Format( CultureInfo::CurrentCulture, "Minimum:{0} Maximum:{1}", Minimum.ToString(), Maximum.ToString() );
\r
211 int BoundingBox::GetHashCode()
\r
213 return Minimum.GetHashCode() + Maximum.GetHashCode();
\r
216 bool BoundingBox::Equals( Object^ value )
\r
218 if( value == nullptr )
\r
221 if( value->GetType() != GetType() )
\r
224 return Equals( safe_cast<BoundingBox>( value ) );
\r
227 bool BoundingBox::Equals( BoundingBox value )
\r
229 return ( Minimum == value.Minimum && Maximum == value.Maximum );
\r
232 bool BoundingBox::Equals( BoundingBox% value1, BoundingBox% value2 )
\r
234 return ( value1.Minimum == value2.Minimum && value1.Maximum == value2.Maximum );
\r