push d1f5df181c120dbe494f7c89b454752c2e0dcc04
[wine/hacks.git] / dlls / d3dx8 / mesh.c
blob88e9b87867f74ade782421849d6e8d545f038524
1 /*
2 * Copyright 2008 David Adam
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "windef.h"
20 #include "wingdi.h"
21 #include "d3dx8.h"
23 BOOL WINAPI D3DXBoxBoundProbe(CONST D3DXVECTOR3 *pmin, CONST D3DXVECTOR3 *pmax, CONST D3DXVECTOR3 *prayposition, CONST D3DXVECTOR3 *praydirection)
25 /* Algorithm taken from the article: An Efficient and Robust Ray-Box Intersection Algoritm
26 Amy Williams University of Utah
27 Steve Barrus University of Utah
28 R. Keith Morley University of Utah
29 Peter Shirley University of Utah
31 International Conference on Computer Graphics and Interactive Techniques archive
32 ACM SIGGRAPH 2005 Courses
33 Los Angeles, California
35 This algorithm is free of patents or of copyrights, as confirmed by Peter Shirley himself.
37 Algorithm: Consider the box as the intersection of three slabs. Clip the ray
38 against each slab, if there's anything left of the ray after we're
39 done we've got an intersection of the ray with the box.
43 FLOAT div, tmin, tmax, tymin, tymax, tzmin, tzmax;
45 div = 1.0f / praydirection->x;
46 if ( div >= 0.0f )
48 tmin = ( pmin->x - prayposition->x ) * div;
49 tmax = ( pmax->x - prayposition->x ) * div;
51 else
53 tmin = ( pmax->x - prayposition->x ) * div;
54 tmax = ( pmin->x - prayposition->x ) * div;
57 if ( tmax < 0.0f ) return FALSE;
59 div = 1.0f / praydirection->y;
60 if ( div >= 0.0f )
62 tymin = ( pmin->y - prayposition->y ) * div;
63 tymax = ( pmax->y - prayposition->y ) * div;
65 else
67 tymin = ( pmax->y - prayposition->y ) * div;
68 tymax = ( pmin->y - prayposition->y ) * div;
71 if ( ( tymax < 0.0f ) || ( tmin > tymax ) || ( tymin > tmax ) ) return FALSE;
73 if ( tymin > tmin ) tmin = tymin;
74 if ( tymax < tmax ) tmax = tymax;
76 div = 1.0f / praydirection->z;
77 if ( div >= 0.0f )
79 tzmin = ( pmin->z - prayposition->z ) * div;
80 tzmax = ( pmax->z - prayposition->z ) * div;
82 else
84 tzmin = ( pmax->z - prayposition->z ) * div;
85 tzmax = ( pmin->z - prayposition->z ) * div;
88 if ( (tzmax < 0.0f ) || ( tmin > tzmax ) || ( tzmin > tmax ) ) return FALSE;
90 return TRUE;
93 BOOL CDECL D3DXIntersectTri(CONST D3DXVECTOR3 *p0, CONST D3DXVECTOR3 *p1, CONST D3DXVECTOR3 *p2, CONST D3DXVECTOR3 *praypos, CONST D3DXVECTOR3 *praydir, FLOAT *pu, FLOAT *pv, FLOAT *pdist)
95 D3DXMATRIX m;
96 D3DXVECTOR4 vec;
98 m.m[0][0] = p1->x - p0->x;
99 m.m[1][0] = p2->x - p0->x;
100 m.m[2][0] = -praydir->x;
101 m.m[3][0] = 0.0f;
102 m.m[0][1] = p1->y - p0->z;
103 m.m[1][1] = p2->y - p0->z;
104 m.m[2][1] = -praydir->y;
105 m.m[3][1] = 0.0f;
106 m.m[0][2] = p1->z - p0->z;
107 m.m[1][2] = p2->z - p0->z;
108 m.m[2][2] = -praydir->z;
109 m.m[3][2] = 0.0f;
110 m.m[0][3] = 0.0f;
111 m.m[1][3] = 0.0f;
112 m.m[2][3] = 0.0f;
113 m.m[3][3] = 1.0f;
115 vec.x = praypos->x - p0->x;
116 vec.y = praypos->y - p0->y;
117 vec.z = praypos->z - p0->z;
118 vec.w = 0.0f;
120 if ( D3DXMatrixInverse(&m, NULL, &m) )
122 D3DXVec4Transform(&vec, &vec, &m);
123 if ( (vec.x >= 0.0f) && (vec.y >= 0.0f) && (vec.x + vec.y <= 1.0f) && (vec.z >= 0.0f) )
125 *pu = vec.x;
126 *pv = vec.y;
127 *pdist = fabs( vec.z );
128 return TRUE;
132 return FALSE;
135 BOOL WINAPI D3DXSphereBoundProbe(CONST D3DXVECTOR3 *pcenter, FLOAT radius, CONST D3DXVECTOR3 *prayposition, CONST D3DXVECTOR3 *praydirection)
137 D3DXVECTOR3 difference;
138 FLOAT a, b, c, d;
140 a = D3DXVec3LengthSq(praydirection);
141 if (!D3DXVec3Subtract(&difference, prayposition, pcenter)) return FALSE;
142 b = D3DXVec3Dot(&difference, praydirection);
143 c = D3DXVec3LengthSq(&difference) - radius * radius;
144 d = b * b - a * c;
146 if ( ( d <= 0.0f ) || ( sqrt(d) <= b ) ) return FALSE;
147 return TRUE;