OSDN Git Service

DTXMania089リリースに際してのtag付け。
[dtxmania/dtxmania.git] / 110401(DTXMania089) / SlimDXc_Jun2010(VC++2008) / source / math / BoundingBox.cpp
1 #include "stdafx.h"\r
2 /*\r
3 * Copyright (c) 2007-2010 SlimDX Group\r
4\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
11\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
14\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
21 * THE SOFTWARE.\r
22 */\r
23 \r
24 #include <d3dx9.h>\r
25 \r
26 #include "../SlimDXException.h"\r
27 #include "../DataStream.h"\r
28 \r
29 #include "BoundingBox.h"\r
30 #include "BoundingSphere.h"\r
31 #include "Ray.h"\r
32 #include "Plane.h"\r
33 \r
34 using namespace System;\r
35 using namespace System::Globalization;\r
36 \r
37 namespace SlimDX\r
38 {\r
39         BoundingBox::BoundingBox( Vector3 minimum, Vector3 maximum )\r
40         {\r
41                 Minimum = minimum;\r
42                 Maximum = maximum;\r
43         }\r
44 \r
45         array<Vector3>^ BoundingBox::GetCorners()\r
46         {\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
56                 return results;\r
57         }\r
58 \r
59         ContainmentType BoundingBox::Contains( BoundingBox box1, BoundingBox box2 )\r
60         {\r
61                 if( box1.Maximum.X < box2.Minimum.X || box1.Minimum.X > box2.Maximum.X )\r
62                         return ContainmentType::Disjoint;\r
63 \r
64                 if( box1.Maximum.Y < box2.Minimum.Y || box1.Minimum.Y > box2.Maximum.Y )\r
65                         return ContainmentType::Disjoint;\r
66 \r
67                 if( box1.Maximum.Z < box2.Minimum.Z || box1.Minimum.Z > box2.Maximum.Z )\r
68                         return ContainmentType::Disjoint;\r
69 \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
73 \r
74                 return ContainmentType::Intersects;\r
75         }\r
76 \r
77         ContainmentType BoundingBox::Contains( BoundingBox box, BoundingSphere sphere )\r
78         {\r
79                 float dist;\r
80                 Vector3 clamped;\r
81 \r
82                 Vector3::Clamp( sphere.Center, box.Minimum, box.Maximum, clamped );\r
83 \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
87 \r
88                 dist = (x * x) + (y * y) + (z * z);\r
89                 float radius = sphere.Radius;\r
90 \r
91                 if( dist > (radius * radius) )\r
92                         return ContainmentType::Disjoint;\r
93 \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
100 \r
101                 return ContainmentType::Intersects;\r
102         }\r
103 \r
104         ContainmentType BoundingBox::Contains( BoundingBox box, Vector3 vector )\r
105         {\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
109 \r
110                 return ContainmentType::Disjoint;\r
111         }\r
112 \r
113         BoundingBox BoundingBox::FromPoints( array<Vector3>^ points )\r
114         {\r
115                 if( points == nullptr || points->Length <= 0 )\r
116                         throw gcnew ArgumentNullException( "points" );\r
117 \r
118                 Vector3 min = Vector3( float::MaxValue );\r
119                 Vector3 max = Vector3( float::MinValue );\r
120 \r
121                 for each( Vector3 vector in points )\r
122                 {\r
123                         Vector3::Minimize( min, vector, min );\r
124                         Vector3::Maximize( max, vector, max );\r
125                 }\r
126 \r
127                 return BoundingBox( min, max );\r
128         }\r
129 \r
130         BoundingBox BoundingBox::FromPoints( DataStream^ points, int count, int stride )\r
131         {\r
132                 BoundingBox box;\r
133 \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
136 \r
137                 if( RECORD_SDX( hr ).IsFailure )\r
138                         return BoundingBox();\r
139 \r
140                 return box;\r
141         }\r
142 \r
143         BoundingBox BoundingBox::FromSphere( BoundingSphere sphere )\r
144         {\r
145                 BoundingBox box;\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
148                 return box;\r
149         }\r
150 \r
151         BoundingBox BoundingBox::Merge( BoundingBox box1, BoundingBox box2 )\r
152         {\r
153                 BoundingBox box;\r
154                 Vector3::Minimize( box1.Minimum, box2.Minimum, box.Minimum );\r
155                 Vector3::Maximize( box1.Maximum, box2.Maximum, box.Maximum );\r
156                 return box;\r
157         }\r
158 \r
159         bool BoundingBox::Intersects( BoundingBox box1, BoundingBox box2 )\r
160         {\r
161                 if ( box1.Maximum.X < box2.Minimum.X || box1.Minimum.X > box2.Maximum.X )\r
162                         return false;\r
163 \r
164                 if ( box1.Maximum.Y < box2.Minimum.Y || box1.Minimum.Y > box2.Maximum.Y )\r
165                         return false;\r
166 \r
167                 return ( box1.Maximum.Z >= box2.Minimum.Z && box1.Minimum.Z <= box2.Maximum.Z );\r
168         }\r
169 \r
170         bool BoundingBox::Intersects( BoundingBox box, BoundingSphere sphere )\r
171         {\r
172                 float dist;\r
173                 Vector3 clamped;\r
174 \r
175                 Vector3::Clamp( sphere.Center, box.Minimum, box.Maximum, clamped );\r
176 \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
180 \r
181                 dist = (x * x) + (y * y) + (z * z);\r
182 \r
183                 return ( dist <= (sphere.Radius * sphere.Radius) );\r
184         }\r
185 \r
186         bool BoundingBox::Intersects( BoundingBox box, Ray ray, [Out] float% distance )\r
187         {\r
188                 return Ray::Intersects( ray, box, distance );\r
189         }\r
190 \r
191         PlaneIntersectionType BoundingBox::Intersects( BoundingBox box, Plane plane )\r
192         {\r
193                 return Plane::Intersects( plane, box );\r
194         }\r
195 \r
196         bool BoundingBox::operator == ( BoundingBox left, BoundingBox right )\r
197         {\r
198                 return BoundingBox::Equals( left, right );\r
199         }\r
200 \r
201         bool BoundingBox::operator != ( BoundingBox left, BoundingBox right )\r
202         {\r
203                 return !BoundingBox::Equals( left, right );\r
204         }\r
205 \r
206         String^ BoundingBox::ToString()\r
207         {\r
208                 return String::Format( CultureInfo::CurrentCulture, "Minimum:{0} Maximum:{1}", Minimum.ToString(), Maximum.ToString() );\r
209         }\r
210 \r
211         int BoundingBox::GetHashCode()\r
212         {\r
213                 return Minimum.GetHashCode() + Maximum.GetHashCode();\r
214         }\r
215 \r
216         bool BoundingBox::Equals( Object^ value )\r
217         {\r
218                 if( value == nullptr )\r
219                         return false;\r
220 \r
221                 if( value->GetType() != GetType() )\r
222                         return false;\r
223 \r
224                 return Equals( safe_cast<BoundingBox>( value ) );\r
225         }\r
226 \r
227         bool BoundingBox::Equals( BoundingBox value )\r
228         {\r
229                 return ( Minimum == value.Minimum && Maximum == value.Maximum );\r
230         }\r
231 \r
232         bool BoundingBox::Equals( BoundingBox% value1, BoundingBox% value2 )\r
233         {\r
234                 return ( value1.Minimum == value2.Minimum && value1.Maximum == value2.Maximum );\r
235         }\r
236 }\r