wordpad: Add Ukrainian translations.
[wine/hacks.git] / dlls / d3dx9_36 / mesh.c
blob91116b283411790ba310dfc5167c685e8d707e21
1 /*
2 * Mesh operations specific to D3DX9.
4 * Copyright (C) 2009 David Adam
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
22 #include "wine/port.h"
24 #define NONAMELESSUNION
25 #include "windef.h"
26 #include "wingdi.h"
27 #include "d3dx9.h"
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
32 /*************************************************************************
33 * D3DXBoxBoundProbe
35 BOOL WINAPI D3DXBoxBoundProbe(CONST D3DXVECTOR3 *pmin, CONST D3DXVECTOR3 *pmax, CONST D3DXVECTOR3 *prayposition, CONST D3DXVECTOR3 *praydirection)
37 /* Algorithm taken from the article: An Efficient and Robust Ray-Box Intersection Algoritm
38 Amy Williams University of Utah
39 Steve Barrus University of Utah
40 R. Keith Morley University of Utah
41 Peter Shirley University of Utah
43 International Conference on Computer Graphics and Interactive Techniques archive
44 ACM SIGGRAPH 2005 Courses
45 Los Angeles, California
47 This algorithm is free of patents or of copyrights, as confirmed by Peter Shirley himself.
49 Algorithm: Consider the box as the intersection of three slabs. Clip the ray
50 against each slab, if there's anything left of the ray after we're
51 done we've got an intersection of the ray with the box.
55 FLOAT div, tmin, tmax, tymin, tymax, tzmin, tzmax;
57 div = 1.0f / praydirection->x;
58 if ( div >= 0.0f )
60 tmin = ( pmin->x - prayposition->x ) * div;
61 tmax = ( pmax->x - prayposition->x ) * div;
63 else
65 tmin = ( pmax->x - prayposition->x ) * div;
66 tmax = ( pmin->x - prayposition->x ) * div;
69 if ( tmax < 0.0f ) return FALSE;
71 div = 1.0f / praydirection->y;
72 if ( div >= 0.0f )
74 tymin = ( pmin->y - prayposition->y ) * div;
75 tymax = ( pmax->y - prayposition->y ) * div;
77 else
79 tymin = ( pmax->y - prayposition->y ) * div;
80 tymax = ( pmin->y - prayposition->y ) * div;
83 if ( ( tymax < 0.0f ) || ( tmin > tymax ) || ( tymin > tmax ) ) return FALSE;
85 if ( tymin > tmin ) tmin = tymin;
86 if ( tymax < tmax ) tmax = tymax;
88 div = 1.0f / praydirection->z;
89 if ( div >= 0.0f )
91 tzmin = ( pmin->z - prayposition->z ) * div;
92 tzmax = ( pmax->z - prayposition->z ) * div;
94 else
96 tzmin = ( pmax->z - prayposition->z ) * div;
97 tzmax = ( pmin->z - prayposition->z ) * div;
100 if ( (tzmax < 0.0f ) || ( tmin > tzmax ) || ( tzmin > tmax ) ) return FALSE;
102 return TRUE;
105 /*************************************************************************
106 * D3DXComputeBoundingBox
108 HRESULT WINAPI D3DXComputeBoundingBox(CONST D3DXVECTOR3 *pfirstposition, DWORD numvertices, DWORD dwstride, D3DXVECTOR3 *pmin, D3DXVECTOR3 *pmax)
110 D3DXVECTOR3 vec;
111 unsigned int i;
113 if( !pfirstposition || !pmin || !pmax ) return D3DERR_INVALIDCALL;
115 *pmin = *pfirstposition;
116 *pmax = *pmin;
118 for(i=0; i<numvertices; i++)
120 vec = *( (D3DXVECTOR3*)((char*)pfirstposition + dwstride * i) );
122 if ( vec.x < pmin->x ) pmin->x = vec.x;
123 if ( vec.x > pmax->x ) pmax->x = vec.x;
125 if ( vec.y < pmin->y ) pmin->y = vec.y;
126 if ( vec.y > pmax->y ) pmax->y = vec.y;
128 if ( vec.z < pmin->z ) pmin->z = vec.z;
129 if ( vec.z > pmax->z ) pmax->z = vec.z;
132 return D3D_OK;
135 /*************************************************************************
136 * D3DXComputeBoundingSphere
138 HRESULT WINAPI D3DXComputeBoundingSphere(CONST D3DXVECTOR3* pfirstposition, DWORD numvertices, DWORD dwstride, D3DXVECTOR3 *pcenter, FLOAT *pradius)
140 D3DXVECTOR3 temp, temp1;
141 FLOAT d;
142 unsigned int i;
144 if( !pfirstposition || !pcenter || !pradius ) return D3DERR_INVALIDCALL;
146 temp.x = 0.0f;
147 temp.y = 0.0f;
148 temp.z = 0.0f;
149 temp1 = temp;
150 d = 0.0f;
151 *pradius = 0.0f;
153 for(i=0; i<numvertices; i++)
155 D3DXVec3Add(&temp1, &temp, (D3DXVECTOR3*)((char*)pfirstposition + dwstride * i));
156 temp = temp1;
159 D3DXVec3Scale(pcenter, &temp, 1.0f/((FLOAT)numvertices));
161 for(i=0; i<numvertices; i++)
163 d = D3DXVec3Length(D3DXVec3Subtract(&temp, (D3DXVECTOR3*)((char*)pfirstposition + dwstride * i), pcenter));
164 if ( d > *pradius ) *pradius = d;
166 return D3D_OK;
169 /*************************************************************************
170 * D3DXGetFVFVertexSize
172 static UINT Get_TexCoord_Size_From_FVF(DWORD FVF, int tex_num)
174 return (((((FVF) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1);
177 UINT WINAPI D3DXGetFVFVertexSize(DWORD FVF)
179 DWORD size = 0;
180 UINT i;
181 UINT numTextures = (FVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
183 if (FVF & D3DFVF_NORMAL) size += sizeof(D3DXVECTOR3);
184 if (FVF & D3DFVF_DIFFUSE) size += sizeof(DWORD);
185 if (FVF & D3DFVF_SPECULAR) size += sizeof(DWORD);
186 if (FVF & D3DFVF_PSIZE) size += sizeof(DWORD);
188 switch (FVF & D3DFVF_POSITION_MASK)
190 case D3DFVF_XYZ: size += sizeof(D3DXVECTOR3); break;
191 case D3DFVF_XYZRHW: size += 4 * sizeof(FLOAT); break;
192 case D3DFVF_XYZB1: size += 4 * sizeof(FLOAT); break;
193 case D3DFVF_XYZB2: size += 5 * sizeof(FLOAT); break;
194 case D3DFVF_XYZB3: size += 6 * sizeof(FLOAT); break;
195 case D3DFVF_XYZB4: size += 7 * sizeof(FLOAT); break;
196 case D3DFVF_XYZB5: size += 8 * sizeof(FLOAT); break;
197 case D3DFVF_XYZW: size += 4 * sizeof(FLOAT); break;
200 for (i = 0; i < numTextures; i++)
202 size += Get_TexCoord_Size_From_FVF(FVF, i) * sizeof(FLOAT);
205 return size;
208 /*************************************************************************
209 * D3DXGetDeclVertexSize
211 UINT WINAPI D3DXGetDeclVertexSize(const D3DVERTEXELEMENT9 *decl, DWORD stream_idx)
213 const D3DVERTEXELEMENT9 *element;
214 UINT size = 0;
216 TRACE("decl %p, stream_idx %u\n", decl, stream_idx);
218 if (!decl) return 0;
220 for (element = decl; element->Stream != 0xff; ++element)
222 UINT type_size;
224 if (element->Stream != stream_idx) continue;
226 switch (element->Type)
228 case D3DDECLTYPE_FLOAT1: type_size = 1 * 4; break;
229 case D3DDECLTYPE_FLOAT2: type_size = 2 * 4; break;
230 case D3DDECLTYPE_FLOAT3: type_size = 3 * 4; break;
231 case D3DDECLTYPE_FLOAT4: type_size = 4 * 4; break;
232 case D3DDECLTYPE_D3DCOLOR: type_size = 4 * 1; break;
233 case D3DDECLTYPE_UBYTE4: type_size = 4 * 1; break;
234 case D3DDECLTYPE_SHORT2: type_size = 2 * 2; break;
235 case D3DDECLTYPE_SHORT4: type_size = 4 * 2; break;
236 case D3DDECLTYPE_UBYTE4N: type_size = 4 * 1; break;
237 case D3DDECLTYPE_SHORT2N: type_size = 2 * 2; break;
238 case D3DDECLTYPE_SHORT4N: type_size = 4 * 2; break;
239 case D3DDECLTYPE_USHORT2N: type_size = 2 * 2; break;
240 case D3DDECLTYPE_USHORT4N: type_size = 4 * 2; break;
241 case D3DDECLTYPE_UDEC3: type_size = 4; break; /* 3 * 10 bits + 2 padding */
242 case D3DDECLTYPE_DEC3N: type_size = 4; break;
243 case D3DDECLTYPE_FLOAT16_2: type_size = 2 * 2; break;
244 case D3DDECLTYPE_FLOAT16_4: type_size = 4 * 2; break;
245 default:
246 FIXME("Unhandled element type %#x, size will be incorrect.\n", element->Type);
247 type_size = 0;
248 break;
251 if (element->Offset + type_size > size) size = element->Offset + type_size;
254 return size;
257 /*************************************************************************
258 * D3DXIntersectTri
260 BOOL WINAPI D3DXIntersectTri(CONST D3DXVECTOR3 *p0, CONST D3DXVECTOR3 *p1, CONST D3DXVECTOR3 *p2, CONST D3DXVECTOR3 *praypos, CONST D3DXVECTOR3 *praydir, FLOAT *pu, FLOAT *pv, FLOAT *pdist)
262 D3DXMATRIX m;
263 D3DXVECTOR4 vec;
265 m.u.m[0][0] = p1->x - p0->x;
266 m.u.m[1][0] = p2->x - p0->x;
267 m.u.m[2][0] = -praydir->x;
268 m.u.m[3][0] = 0.0f;
269 m.u.m[0][1] = p1->y - p0->z;
270 m.u.m[1][1] = p2->y - p0->z;
271 m.u.m[2][1] = -praydir->y;
272 m.u.m[3][1] = 0.0f;
273 m.u.m[0][2] = p1->z - p0->z;
274 m.u.m[1][2] = p2->z - p0->z;
275 m.u.m[2][2] = -praydir->z;
276 m.u.m[3][2] = 0.0f;
277 m.u.m[0][3] = 0.0f;
278 m.u.m[1][3] = 0.0f;
279 m.u.m[2][3] = 0.0f;
280 m.u.m[3][3] = 1.0f;
282 vec.x = praypos->x - p0->x;
283 vec.y = praypos->y - p0->y;
284 vec.z = praypos->z - p0->z;
285 vec.w = 0.0f;
287 if ( D3DXMatrixInverse(&m, NULL, &m) )
289 D3DXVec4Transform(&vec, &vec, &m);
290 if ( (vec.x >= 0.0f) && (vec.y >= 0.0f) && (vec.x + vec.y <= 1.0f) && (vec.z >= 0.0f) )
292 *pu = vec.x;
293 *pv = vec.y;
294 *pdist = fabs( vec.z );
295 return TRUE;
299 return FALSE;
302 /*************************************************************************
303 * D3DXSphereBoundProbe
305 BOOL WINAPI D3DXSphereBoundProbe(CONST D3DXVECTOR3 *pcenter, FLOAT radius, CONST D3DXVECTOR3 *prayposition, CONST D3DXVECTOR3 *praydirection)
307 D3DXVECTOR3 difference;
308 FLOAT a, b, c, d;
310 a = D3DXVec3LengthSq(praydirection);
311 if (!D3DXVec3Subtract(&difference, prayposition, pcenter)) return FALSE;
312 b = D3DXVec3Dot(&difference, praydirection);
313 c = D3DXVec3LengthSq(&difference) - radius * radius;
314 d = b * b - a * c;
316 if ( ( d <= 0.0f ) || ( sqrt(d) <= b ) ) return FALSE;
317 return TRUE;