winecfg: Update Portuguese translation.
[wine/testsucceed.git] / dlls / d3dx9_36 / mesh.c
blob9691eed8edc790a6548a1dc3fb4bac58f47d8373
1 /*
2 * Mesh operations specific to D3DX9.
4 * Copyright (C) 2009 David Adam
5 * Copyright (C) 2010 Tony Wasserka
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "config.h"
23 #include "wine/port.h"
25 #define NONAMELESSUNION
26 #include "windef.h"
27 #include "wingdi.h"
28 #include "d3dx9.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
33 /*************************************************************************
34 * D3DXBoxBoundProbe
36 BOOL WINAPI D3DXBoxBoundProbe(CONST D3DXVECTOR3 *pmin, CONST D3DXVECTOR3 *pmax, CONST D3DXVECTOR3 *prayposition, CONST D3DXVECTOR3 *praydirection)
38 /* Algorithm taken from the article: An Efficient and Robust Ray-Box Intersection Algoritm
39 Amy Williams University of Utah
40 Steve Barrus University of Utah
41 R. Keith Morley University of Utah
42 Peter Shirley University of Utah
44 International Conference on Computer Graphics and Interactive Techniques archive
45 ACM SIGGRAPH 2005 Courses
46 Los Angeles, California
48 This algorithm is free of patents or of copyrights, as confirmed by Peter Shirley himself.
50 Algorithm: Consider the box as the intersection of three slabs. Clip the ray
51 against each slab, if there's anything left of the ray after we're
52 done we've got an intersection of the ray with the box.
56 FLOAT div, tmin, tmax, tymin, tymax, tzmin, tzmax;
58 div = 1.0f / praydirection->x;
59 if ( div >= 0.0f )
61 tmin = ( pmin->x - prayposition->x ) * div;
62 tmax = ( pmax->x - prayposition->x ) * div;
64 else
66 tmin = ( pmax->x - prayposition->x ) * div;
67 tmax = ( pmin->x - prayposition->x ) * div;
70 if ( tmax < 0.0f ) return FALSE;
72 div = 1.0f / praydirection->y;
73 if ( div >= 0.0f )
75 tymin = ( pmin->y - prayposition->y ) * div;
76 tymax = ( pmax->y - prayposition->y ) * div;
78 else
80 tymin = ( pmax->y - prayposition->y ) * div;
81 tymax = ( pmin->y - prayposition->y ) * div;
84 if ( ( tymax < 0.0f ) || ( tmin > tymax ) || ( tymin > tmax ) ) return FALSE;
86 if ( tymin > tmin ) tmin = tymin;
87 if ( tymax < tmax ) tmax = tymax;
89 div = 1.0f / praydirection->z;
90 if ( div >= 0.0f )
92 tzmin = ( pmin->z - prayposition->z ) * div;
93 tzmax = ( pmax->z - prayposition->z ) * div;
95 else
97 tzmin = ( pmax->z - prayposition->z ) * div;
98 tzmax = ( pmin->z - prayposition->z ) * div;
101 if ( (tzmax < 0.0f ) || ( tmin > tzmax ) || ( tzmin > tmax ) ) return FALSE;
103 return TRUE;
106 /*************************************************************************
107 * D3DXComputeBoundingBox
109 HRESULT WINAPI D3DXComputeBoundingBox(CONST D3DXVECTOR3 *pfirstposition, DWORD numvertices, DWORD dwstride, D3DXVECTOR3 *pmin, D3DXVECTOR3 *pmax)
111 D3DXVECTOR3 vec;
112 unsigned int i;
114 if( !pfirstposition || !pmin || !pmax ) return D3DERR_INVALIDCALL;
116 *pmin = *pfirstposition;
117 *pmax = *pmin;
119 for(i=0; i<numvertices; i++)
121 vec = *( (const D3DXVECTOR3*)((const char*)pfirstposition + dwstride * i) );
123 if ( vec.x < pmin->x ) pmin->x = vec.x;
124 if ( vec.x > pmax->x ) pmax->x = vec.x;
126 if ( vec.y < pmin->y ) pmin->y = vec.y;
127 if ( vec.y > pmax->y ) pmax->y = vec.y;
129 if ( vec.z < pmin->z ) pmin->z = vec.z;
130 if ( vec.z > pmax->z ) pmax->z = vec.z;
133 return D3D_OK;
136 /*************************************************************************
137 * D3DXComputeBoundingSphere
139 HRESULT WINAPI D3DXComputeBoundingSphere(CONST D3DXVECTOR3* pfirstposition, DWORD numvertices, DWORD dwstride, D3DXVECTOR3 *pcenter, FLOAT *pradius)
141 D3DXVECTOR3 temp, temp1;
142 FLOAT d;
143 unsigned int i;
145 if( !pfirstposition || !pcenter || !pradius ) return D3DERR_INVALIDCALL;
147 temp.x = 0.0f;
148 temp.y = 0.0f;
149 temp.z = 0.0f;
150 temp1 = temp;
151 d = 0.0f;
152 *pradius = 0.0f;
154 for(i=0; i<numvertices; i++)
156 D3DXVec3Add(&temp1, &temp, (const D3DXVECTOR3*)((const char*)pfirstposition + dwstride * i));
157 temp = temp1;
160 D3DXVec3Scale(pcenter, &temp, 1.0f/((FLOAT)numvertices));
162 for(i=0; i<numvertices; i++)
164 d = D3DXVec3Length(D3DXVec3Subtract(&temp, (const D3DXVECTOR3*)((const char*)pfirstposition + dwstride * i), pcenter));
165 if ( d > *pradius ) *pradius = d;
167 return D3D_OK;
170 /*************************************************************************
171 * D3DXDeclaratorFromFVF
173 HRESULT WINAPI D3DXDeclaratorFromFVF(DWORD fvf, D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE])
175 FIXME("(%d, %p): stub\n", fvf, Declaration);
177 return E_NOTIMPL;
180 /*************************************************************************
181 * D3DXGetFVFVertexSize
183 static UINT Get_TexCoord_Size_From_FVF(DWORD FVF, int tex_num)
185 return (((((FVF) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1);
188 UINT WINAPI D3DXGetFVFVertexSize(DWORD FVF)
190 DWORD size = 0;
191 UINT i;
192 UINT numTextures = (FVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
194 if (FVF & D3DFVF_NORMAL) size += sizeof(D3DXVECTOR3);
195 if (FVF & D3DFVF_DIFFUSE) size += sizeof(DWORD);
196 if (FVF & D3DFVF_SPECULAR) size += sizeof(DWORD);
197 if (FVF & D3DFVF_PSIZE) size += sizeof(DWORD);
199 switch (FVF & D3DFVF_POSITION_MASK)
201 case D3DFVF_XYZ: size += sizeof(D3DXVECTOR3); break;
202 case D3DFVF_XYZRHW: size += 4 * sizeof(FLOAT); break;
203 case D3DFVF_XYZB1: size += 4 * sizeof(FLOAT); break;
204 case D3DFVF_XYZB2: size += 5 * sizeof(FLOAT); break;
205 case D3DFVF_XYZB3: size += 6 * sizeof(FLOAT); break;
206 case D3DFVF_XYZB4: size += 7 * sizeof(FLOAT); break;
207 case D3DFVF_XYZB5: size += 8 * sizeof(FLOAT); break;
208 case D3DFVF_XYZW: size += 4 * sizeof(FLOAT); break;
211 for (i = 0; i < numTextures; i++)
213 size += Get_TexCoord_Size_From_FVF(FVF, i) * sizeof(FLOAT);
216 return size;
219 /*************************************************************************
220 * D3DXGetDeclVertexSize
222 UINT WINAPI D3DXGetDeclVertexSize(const D3DVERTEXELEMENT9 *decl, DWORD stream_idx)
224 const D3DVERTEXELEMENT9 *element;
225 UINT size = 0;
227 TRACE("decl %p, stream_idx %u\n", decl, stream_idx);
229 if (!decl) return 0;
231 for (element = decl; element->Stream != 0xff; ++element)
233 UINT type_size;
235 if (element->Stream != stream_idx) continue;
237 switch (element->Type)
239 case D3DDECLTYPE_FLOAT1: type_size = 1 * 4; break;
240 case D3DDECLTYPE_FLOAT2: type_size = 2 * 4; break;
241 case D3DDECLTYPE_FLOAT3: type_size = 3 * 4; break;
242 case D3DDECLTYPE_FLOAT4: type_size = 4 * 4; break;
243 case D3DDECLTYPE_D3DCOLOR: type_size = 4 * 1; break;
244 case D3DDECLTYPE_UBYTE4: type_size = 4 * 1; break;
245 case D3DDECLTYPE_SHORT2: type_size = 2 * 2; break;
246 case D3DDECLTYPE_SHORT4: type_size = 4 * 2; break;
247 case D3DDECLTYPE_UBYTE4N: type_size = 4 * 1; break;
248 case D3DDECLTYPE_SHORT2N: type_size = 2 * 2; break;
249 case D3DDECLTYPE_SHORT4N: type_size = 4 * 2; break;
250 case D3DDECLTYPE_USHORT2N: type_size = 2 * 2; break;
251 case D3DDECLTYPE_USHORT4N: type_size = 4 * 2; break;
252 case D3DDECLTYPE_UDEC3: type_size = 4; break; /* 3 * 10 bits + 2 padding */
253 case D3DDECLTYPE_DEC3N: type_size = 4; break;
254 case D3DDECLTYPE_FLOAT16_2: type_size = 2 * 2; break;
255 case D3DDECLTYPE_FLOAT16_4: type_size = 4 * 2; break;
256 default:
257 FIXME("Unhandled element type %#x, size will be incorrect.\n", element->Type);
258 type_size = 0;
259 break;
262 if (element->Offset + type_size > size) size = element->Offset + type_size;
265 return size;
268 /*************************************************************************
269 * D3DXIntersectTri
271 BOOL WINAPI D3DXIntersectTri(CONST D3DXVECTOR3 *p0, CONST D3DXVECTOR3 *p1, CONST D3DXVECTOR3 *p2, CONST D3DXVECTOR3 *praypos, CONST D3DXVECTOR3 *praydir, FLOAT *pu, FLOAT *pv, FLOAT *pdist)
273 D3DXMATRIX m;
274 D3DXVECTOR4 vec;
276 m.u.m[0][0] = p1->x - p0->x;
277 m.u.m[1][0] = p2->x - p0->x;
278 m.u.m[2][0] = -praydir->x;
279 m.u.m[3][0] = 0.0f;
280 m.u.m[0][1] = p1->y - p0->z;
281 m.u.m[1][1] = p2->y - p0->z;
282 m.u.m[2][1] = -praydir->y;
283 m.u.m[3][1] = 0.0f;
284 m.u.m[0][2] = p1->z - p0->z;
285 m.u.m[1][2] = p2->z - p0->z;
286 m.u.m[2][2] = -praydir->z;
287 m.u.m[3][2] = 0.0f;
288 m.u.m[0][3] = 0.0f;
289 m.u.m[1][3] = 0.0f;
290 m.u.m[2][3] = 0.0f;
291 m.u.m[3][3] = 1.0f;
293 vec.x = praypos->x - p0->x;
294 vec.y = praypos->y - p0->y;
295 vec.z = praypos->z - p0->z;
296 vec.w = 0.0f;
298 if ( D3DXMatrixInverse(&m, NULL, &m) )
300 D3DXVec4Transform(&vec, &vec, &m);
301 if ( (vec.x >= 0.0f) && (vec.y >= 0.0f) && (vec.x + vec.y <= 1.0f) && (vec.z >= 0.0f) )
303 *pu = vec.x;
304 *pv = vec.y;
305 *pdist = fabs( vec.z );
306 return TRUE;
310 return FALSE;
313 /*************************************************************************
314 * D3DXSphereBoundProbe
316 BOOL WINAPI D3DXSphereBoundProbe(CONST D3DXVECTOR3 *pcenter, FLOAT radius, CONST D3DXVECTOR3 *prayposition, CONST D3DXVECTOR3 *praydirection)
318 D3DXVECTOR3 difference;
319 FLOAT a, b, c, d;
321 a = D3DXVec3LengthSq(praydirection);
322 if (!D3DXVec3Subtract(&difference, prayposition, pcenter)) return FALSE;
323 b = D3DXVec3Dot(&difference, praydirection);
324 c = D3DXVec3LengthSq(&difference) - radius * radius;
325 d = b * b - a * c;
327 if ( ( d <= 0.0f ) || ( sqrt(d) <= b ) ) return FALSE;
328 return TRUE;
331 HRESULT WINAPI D3DXCreateBox(LPDIRECT3DDEVICE9 device, FLOAT width, FLOAT height,
332 FLOAT depth, LPD3DXMESH* mesh, LPD3DXBUFFER* adjacency)
334 FIXME("(%p, %f, %f, %f, %p, %p): stub\n", device, width, height, depth, mesh, adjacency);
336 return E_NOTIMPL;