OSDN Git Service

作業部屋#50802 画面キャプチャができなくなっていた問題を暫定対応(F12キー固定で対応中)
[dtxmaniaxg-verk/dtxmaniaxg-verk-git.git] / SlimDXc_Jun2010(VC++2008) / source / math / BoundingSphere.cpp
1 #include "stdafx.h"
2 /*
3 * Copyright (c) 2007-2010 SlimDX Group
4
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24 #include <d3dx9.h>
25
26 #include "../SlimDXException.h"
27
28 #include "BoundingSphere.h"
29 #include "BoundingBox.h"
30 #include "Ray.h"
31 #include "Plane.h"
32
33 using namespace System;
34 using namespace System::Globalization;
35
36 namespace SlimDX
37 {
38         BoundingSphere::BoundingSphere( Vector3 center, float radius )
39         {
40                 Center = center;
41                 Radius = radius;
42         }
43
44         ContainmentType BoundingSphere::Contains( BoundingSphere sphere, BoundingBox box )
45         {
46                 Vector3 vector;
47
48                 if( !BoundingBox::Intersects( box, sphere ) )
49                         return ContainmentType::Disjoint;
50
51                 float radius = sphere.Radius * sphere.Radius;
52                 vector.X = sphere.Center.X - box.Minimum.X;
53                 vector.Y = sphere.Center.Y - box.Maximum.Y;
54                 vector.Z = sphere.Center.Z - box.Maximum.Z;
55
56                 if( vector.LengthSquared() > radius )
57                         return ContainmentType::Intersects;
58
59                 vector.X = sphere.Center.X - box.Maximum.X;
60                 vector.Y = sphere.Center.Y - box.Maximum.Y;
61                 vector.Z = sphere.Center.Z - box.Maximum.Z;
62
63                 if( vector.LengthSquared() > radius )
64                         return ContainmentType::Intersects;
65
66                 vector.X = sphere.Center.X - box.Maximum.X;
67                 vector.Y = sphere.Center.Y - box.Minimum.Y;
68                 vector.Z = sphere.Center.Z - box.Maximum.Z;
69
70                 if( vector.LengthSquared() > radius )
71                         return ContainmentType::Intersects;
72
73                 vector.X = sphere.Center.X - box.Minimum.X;
74                 vector.Y = sphere.Center.Y - box.Minimum.Y;
75                 vector.Z = sphere.Center.Z - box.Maximum.Z;
76
77                 if( vector.LengthSquared() > radius )
78                         return ContainmentType::Intersects;
79
80                 vector.X = sphere.Center.X - box.Minimum.X;
81                 vector.Y = sphere.Center.Y - box.Maximum.Y;
82                 vector.Z = sphere.Center.Z - box.Minimum.Z;
83
84                 if( vector.LengthSquared() > radius )
85                         return ContainmentType::Intersects;
86
87                 vector.X = sphere.Center.X - box.Maximum.X;
88                 vector.Y = sphere.Center.Y - box.Maximum.Y;
89                 vector.Z = sphere.Center.Z - box.Minimum.Z;
90
91                 if( vector.LengthSquared() > radius )
92                         return ContainmentType::Intersects;
93
94                 vector.X = sphere.Center.X - box.Maximum.X;
95                 vector.Y = sphere.Center.Y - box.Minimum.Y;
96                 vector.Z = sphere.Center.Z - box.Minimum.Z;
97
98                 if( vector.LengthSquared() > radius )
99                         return ContainmentType::Intersects;
100
101                 vector.X = sphere.Center.X - box.Minimum.X;
102                 vector.Y = sphere.Center.Y - box.Minimum.Y;
103                 vector.Z = sphere.Center.Z - box.Minimum.Z;
104
105                 if( vector.LengthSquared() > radius )
106                         return ContainmentType::Intersects;
107
108                 return ContainmentType::Contains;
109         }
110
111         ContainmentType BoundingSphere::Contains( BoundingSphere sphere1, BoundingSphere sphere2 )
112         {
113                 float distance;
114                 float x = sphere1.Center.X - sphere2.Center.X;
115                 float y = sphere1.Center.Y - sphere2.Center.Y;
116                 float z = sphere1.Center.Z - sphere2.Center.Z;
117
118                 distance = static_cast<float>( Math::Sqrt( (x * x) + (y * y) + (z * z) ) );
119                 float radius = sphere1.Radius;
120                 float radius2 = sphere2.Radius;
121
122                 if( radius + radius2 < distance )
123                         return ContainmentType::Disjoint;
124
125                 if( radius - radius2 < distance )
126                         return ContainmentType::Intersects;
127
128                 return ContainmentType::Contains;
129         }
130
131         ContainmentType BoundingSphere::Contains( BoundingSphere sphere, Vector3 vector )
132         {
133                 float x = vector.X - sphere.Center.X;
134                 float y = vector.Y - sphere.Center.Y;
135                 float z = vector.Z - sphere.Center.Z;
136
137                 float distance = (x * x) + (y * y) + (z * z);
138
139                 if( distance >= (sphere.Radius * sphere.Radius) )
140                         return ContainmentType::Disjoint;
141
142                 return ContainmentType::Contains;
143         }
144
145         BoundingSphere BoundingSphere::FromBox( BoundingBox box )
146         {
147                 BoundingSphere sphere;
148                 Vector3::Lerp( box.Minimum, box.Maximum, 0.5f, sphere.Center );
149
150                 float x = box.Minimum.X - box.Maximum.X;
151                 float y = box.Minimum.Y - box.Maximum.Y;
152                 float z = box.Minimum.Z - box.Maximum.Z;
153
154                 float distance = static_cast<float>( Math::Sqrt( (x * x) + (y * y) + (z * z) ) );
155
156                 sphere.Radius = distance * 0.5f;
157
158                 return sphere;
159         }
160
161         BoundingSphere BoundingSphere::FromPoints( array<Vector3>^ points )
162         {
163                 D3DXVECTOR3 center;
164                 FLOAT radius;
165                 pin_ptr<Vector3> pinnedPoints = &points[0];
166
167                 HRESULT hr = D3DXComputeBoundingSphere( reinterpret_cast<const D3DXVECTOR3*>( pinnedPoints ), points->Length, sizeof(float) * 3, &center, &radius );
168                 if( RECORD_SDX( hr ).IsFailure )
169                         return BoundingSphere();
170
171                 BoundingSphere sphere;
172                 sphere.Center = Vector3( center.x, center.y, center.z );
173                 sphere.Radius = radius;
174
175                 return sphere;
176         }
177
178         BoundingSphere BoundingSphere::Merge( BoundingSphere sphere1, BoundingSphere sphere2 )
179         {
180                 BoundingSphere sphere;
181                 Vector3 difference = sphere2.Center - sphere1.Center;
182
183                 float length = difference.Length();
184                 float radius = sphere1.Radius;
185                 float radius2 = sphere2.Radius;
186
187                 if( radius + radius2 >= length)
188                 {
189                         if( radius - radius2 >= length )
190                                 return sphere1;
191
192                         if( radius2 - radius >= length )
193                                 return sphere2;
194                 }
195
196                 Vector3 vector = difference * ( 1.0f / length );
197                 float min = Math::Min( -radius, length - radius2 );
198                 float max = ( Math::Max( radius, length + radius2 ) - min ) * 0.5f;
199
200                 sphere.Center = sphere1.Center + vector * ( max + min );
201                 sphere.Radius = max;
202
203                 return sphere;
204         }
205
206         bool BoundingSphere::Intersects( BoundingSphere sphere, BoundingBox box )
207         {
208                 return BoundingBox::Intersects( box, sphere );
209         }
210
211         bool BoundingSphere::Intersects( BoundingSphere sphere1, BoundingSphere sphere2 )
212         {
213                 float distance;
214                 distance = Vector3::DistanceSquared( sphere1.Center, sphere2.Center );
215                 float radius = sphere1.Radius;
216                 float radius2 = sphere2.Radius;
217
218                 if( (radius * radius) + (2.0f * radius * radius2) + (radius2 * radius2) <= distance )
219                         return false;
220
221                 return true;
222         }
223
224         bool BoundingSphere::Intersects( BoundingSphere sphere, Ray ray, [Out] float% distance )
225         {
226                 return Ray::Intersects( ray, sphere, distance );
227         }
228
229         PlaneIntersectionType BoundingSphere::Intersects( BoundingSphere sphere, Plane plane )
230         {
231                 return Plane::Intersects( plane, sphere );
232         }
233
234         bool BoundingSphere::operator == ( BoundingSphere left, BoundingSphere right )
235         {
236                 return BoundingSphere::Equals( left, right );
237         }
238
239         bool BoundingSphere::operator != ( BoundingSphere left, BoundingSphere right )
240         {
241                 return !BoundingSphere::Equals( left, right );
242         }
243
244         String^ BoundingSphere::ToString()
245         {
246                 return String::Format( CultureInfo::CurrentCulture, "Center:{0} Radius:{1}", Center.ToString(), Radius.ToString(CultureInfo::CurrentCulture) );
247         }
248
249         int BoundingSphere::GetHashCode()
250         {
251                 return Center.GetHashCode() + Radius.GetHashCode();
252         }
253
254         bool BoundingSphere::Equals( Object^ value )
255         {
256                 if( value == nullptr )
257                         return false;
258
259                 if( value->GetType() != GetType() )
260                         return false;
261
262                 return Equals( safe_cast<BoundingSphere>( value ) );
263         }
264
265         bool BoundingSphere::Equals( BoundingSphere value )
266         {
267                 return ( Center == value.Center && Radius == value.Radius );
268         }
269
270         bool BoundingSphere::Equals( BoundingSphere% value1, BoundingSphere% value2 )
271         {
272                 return ( value1.Center == value2.Center && value1.Radius == value2.Radius );
273         }
274 }