Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmesh.c
Go to the documentation of this file.
00001 /* 00002 * Mesh operations specific to D3DX9. 00003 * 00004 * Copyright (C) 2009 David Adam 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include "config.h" 00022 #include "wine/port.h" 00023 00024 #define NONAMELESSUNION 00025 #include "windef.h" 00026 #include "wingdi.h" 00027 #include "d3dx9.h" 00028 #include "wine/debug.h" 00029 00030 WINE_DEFAULT_DEBUG_CHANNEL(d3dx); 00031 00032 /************************************************************************* 00033 * D3DXBoxBoundProbe 00034 */ 00035 BOOL WINAPI D3DXBoxBoundProbe(CONST D3DXVECTOR3 *pmin, CONST D3DXVECTOR3 *pmax, CONST D3DXVECTOR3 *prayposition, CONST D3DXVECTOR3 *praydirection) 00036 00037 /* Algorithm taken from the article: An Efficient and Robust Ray-Box Intersection Algoritm 00038 Amy Williams University of Utah 00039 Steve Barrus University of Utah 00040 R. Keith Morley University of Utah 00041 Peter Shirley University of Utah 00042 00043 International Conference on Computer Graphics and Interactive Techniques archive 00044 ACM SIGGRAPH 2005 Courses 00045 Los Angeles, California 00046 00047 This algorithm is free of patents or of copyrights, as confirmed by Peter Shirley himself. 00048 00049 Algorithm: Consider the box as the intersection of three slabs. Clip the ray 00050 against each slab, if there's anything left of the ray after we're 00051 done we've got an intersection of the ray with the box. 00052 */ 00053 00054 { 00055 FLOAT div, tmin, tmax, tymin, tymax, tzmin, tzmax; 00056 00057 div = 1.0f / praydirection->x; 00058 if ( div >= 0.0f ) 00059 { 00060 tmin = ( pmin->x - prayposition->x ) * div; 00061 tmax = ( pmax->x - prayposition->x ) * div; 00062 } 00063 else 00064 { 00065 tmin = ( pmax->x - prayposition->x ) * div; 00066 tmax = ( pmin->x - prayposition->x ) * div; 00067 } 00068 00069 if ( tmax < 0.0f ) return FALSE; 00070 00071 div = 1.0f / praydirection->y; 00072 if ( div >= 0.0f ) 00073 { 00074 tymin = ( pmin->y - prayposition->y ) * div; 00075 tymax = ( pmax->y - prayposition->y ) * div; 00076 } 00077 else 00078 { 00079 tymin = ( pmax->y - prayposition->y ) * div; 00080 tymax = ( pmin->y - prayposition->y ) * div; 00081 } 00082 00083 if ( ( tymax < 0.0f ) || ( tmin > tymax ) || ( tymin > tmax ) ) return FALSE; 00084 00085 if ( tymin > tmin ) tmin = tymin; 00086 if ( tymax < tmax ) tmax = tymax; 00087 00088 div = 1.0f / praydirection->z; 00089 if ( div >= 0.0f ) 00090 { 00091 tzmin = ( pmin->z - prayposition->z ) * div; 00092 tzmax = ( pmax->z - prayposition->z ) * div; 00093 } 00094 else 00095 { 00096 tzmin = ( pmax->z - prayposition->z ) * div; 00097 tzmax = ( pmin->z - prayposition->z ) * div; 00098 } 00099 00100 if ( (tzmax < 0.0f ) || ( tmin > tzmax ) || ( tzmin > tmax ) ) return FALSE; 00101 00102 return TRUE; 00103 } 00104 00105 /************************************************************************* 00106 * D3DXComputeBoundingBox 00107 */ 00108 HRESULT WINAPI D3DXComputeBoundingBox(CONST D3DXVECTOR3 *pfirstposition, DWORD numvertices, DWORD dwstride, D3DXVECTOR3 *pmin, D3DXVECTOR3 *pmax) 00109 { 00110 D3DXVECTOR3 vec; 00111 unsigned int i; 00112 00113 if( !pfirstposition || !pmin || !pmax ) return D3DERR_INVALIDCALL; 00114 00115 *pmin = *pfirstposition; 00116 *pmax = *pmin; 00117 00118 for(i=0; i<numvertices; i++) 00119 { 00120 vec = *( (D3DXVECTOR3*)((char*)pfirstposition + dwstride * i) ); 00121 00122 if ( vec.x < pmin->x ) pmin->x = vec.x; 00123 if ( vec.x > pmax->x ) pmax->x = vec.x; 00124 00125 if ( vec.y < pmin->y ) pmin->y = vec.y; 00126 if ( vec.y > pmax->y ) pmax->y = vec.y; 00127 00128 if ( vec.z < pmin->z ) pmin->z = vec.z; 00129 if ( vec.z > pmax->z ) pmax->z = vec.z; 00130 } 00131 00132 return D3D_OK; 00133 } 00134 00135 /************************************************************************* 00136 * D3DXComputeBoundingSphere 00137 */ 00138 HRESULT WINAPI D3DXComputeBoundingSphere(CONST D3DXVECTOR3* pfirstposition, DWORD numvertices, DWORD dwstride, D3DXVECTOR3 *pcenter, FLOAT *pradius) 00139 { 00140 D3DXVECTOR3 temp, temp1; 00141 FLOAT d; 00142 unsigned int i; 00143 00144 if( !pfirstposition || !pcenter || !pradius ) return D3DERR_INVALIDCALL; 00145 00146 temp.x = 0.0f; 00147 temp.y = 0.0f; 00148 temp.z = 0.0f; 00149 temp1 = temp; 00150 d = 0.0f; 00151 *pradius = 0.0f; 00152 00153 for(i=0; i<numvertices; i++) 00154 { 00155 D3DXVec3Add(&temp1, &temp, (D3DXVECTOR3*)((char*)pfirstposition + dwstride * i)); 00156 temp = temp1; 00157 } 00158 00159 D3DXVec3Scale(pcenter, &temp, 1.0f/((FLOAT)numvertices)); 00160 00161 for(i=0; i<numvertices; i++) 00162 { 00163 d = D3DXVec3Length(D3DXVec3Subtract(&temp, (D3DXVECTOR3*)((char*)pfirstposition + dwstride * i), pcenter)); 00164 if ( d > *pradius ) *pradius = d; 00165 } 00166 return D3D_OK; 00167 } 00168 00169 /************************************************************************* 00170 * D3DXGetFVFVertexSize 00171 */ 00172 static UINT Get_TexCoord_Size_From_FVF(DWORD FVF, int tex_num) 00173 { 00174 return (((((FVF) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1); 00175 } 00176 00177 UINT WINAPI D3DXGetFVFVertexSize(DWORD FVF) 00178 { 00179 DWORD size = 0; 00180 UINT i; 00181 UINT numTextures = (FVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT; 00182 00183 if (FVF & D3DFVF_NORMAL) size += sizeof(D3DXVECTOR3); 00184 if (FVF & D3DFVF_DIFFUSE) size += sizeof(DWORD); 00185 if (FVF & D3DFVF_SPECULAR) size += sizeof(DWORD); 00186 if (FVF & D3DFVF_PSIZE) size += sizeof(DWORD); 00187 00188 switch (FVF & D3DFVF_POSITION_MASK) 00189 { 00190 case D3DFVF_XYZ: size += sizeof(D3DXVECTOR3); break; 00191 case D3DFVF_XYZRHW: size += 4 * sizeof(FLOAT); break; 00192 case D3DFVF_XYZB1: size += 4 * sizeof(FLOAT); break; 00193 case D3DFVF_XYZB2: size += 5 * sizeof(FLOAT); break; 00194 case D3DFVF_XYZB3: size += 6 * sizeof(FLOAT); break; 00195 case D3DFVF_XYZB4: size += 7 * sizeof(FLOAT); break; 00196 case D3DFVF_XYZB5: size += 8 * sizeof(FLOAT); break; 00197 case D3DFVF_XYZW: size += 4 * sizeof(FLOAT); break; 00198 } 00199 00200 for (i = 0; i < numTextures; i++) 00201 { 00202 size += Get_TexCoord_Size_From_FVF(FVF, i) * sizeof(FLOAT); 00203 } 00204 00205 return size; 00206 } 00207 00208 /************************************************************************* 00209 * D3DXGetDeclVertexSize 00210 */ 00211 UINT WINAPI D3DXGetDeclVertexSize(const D3DVERTEXELEMENT9 *decl, DWORD stream_idx) 00212 { 00213 const D3DVERTEXELEMENT9 *element; 00214 UINT size = 0; 00215 00216 TRACE("decl %p, stream_idx %u\n", decl, stream_idx); 00217 00218 if (!decl) return 0; 00219 00220 for (element = decl; element->Stream != 0xff; ++element) 00221 { 00222 UINT type_size; 00223 00224 if (element->Stream != stream_idx) continue; 00225 00226 switch (element->Type) 00227 { 00228 case D3DDECLTYPE_FLOAT1: type_size = 1 * 4; break; 00229 case D3DDECLTYPE_FLOAT2: type_size = 2 * 4; break; 00230 case D3DDECLTYPE_FLOAT3: type_size = 3 * 4; break; 00231 case D3DDECLTYPE_FLOAT4: type_size = 4 * 4; break; 00232 case D3DDECLTYPE_D3DCOLOR: type_size = 4 * 1; break; 00233 case D3DDECLTYPE_UBYTE4: type_size = 4 * 1; break; 00234 case D3DDECLTYPE_SHORT2: type_size = 2 * 2; break; 00235 case D3DDECLTYPE_SHORT4: type_size = 4 * 2; break; 00236 case D3DDECLTYPE_UBYTE4N: type_size = 4 * 1; break; 00237 case D3DDECLTYPE_SHORT2N: type_size = 2 * 2; break; 00238 case D3DDECLTYPE_SHORT4N: type_size = 4 * 2; break; 00239 case D3DDECLTYPE_USHORT2N: type_size = 2 * 2; break; 00240 case D3DDECLTYPE_USHORT4N: type_size = 4 * 2; break; 00241 case D3DDECLTYPE_UDEC3: type_size = 4; break; /* 3 * 10 bits + 2 padding */ 00242 case D3DDECLTYPE_DEC3N: type_size = 4; break; 00243 case D3DDECLTYPE_FLOAT16_2: type_size = 2 * 2; break; 00244 case D3DDECLTYPE_FLOAT16_4: type_size = 4 * 2; break; 00245 default: 00246 FIXME("Unhandled element type %#x, size will be incorrect.\n", element->Type); 00247 type_size = 0; 00248 break; 00249 } 00250 00251 if (element->Offset + type_size > size) size = element->Offset + type_size; 00252 } 00253 00254 return size; 00255 } 00256 00257 /************************************************************************* 00258 * D3DXIntersectTri 00259 */ 00260 BOOL WINAPI D3DXIntersectTri(CONST D3DXVECTOR3 *p0, CONST D3DXVECTOR3 *p1, CONST D3DXVECTOR3 *p2, CONST D3DXVECTOR3 *praypos, CONST D3DXVECTOR3 *praydir, FLOAT *pu, FLOAT *pv, FLOAT *pdist) 00261 { 00262 D3DXMATRIX m; 00263 D3DXVECTOR4 vec; 00264 00265 m.u.m[0][0] = p1->x - p0->x; 00266 m.u.m[1][0] = p2->x - p0->x; 00267 m.u.m[2][0] = -praydir->x; 00268 m.u.m[3][0] = 0.0f; 00269 m.u.m[0][1] = p1->y - p0->z; 00270 m.u.m[1][1] = p2->y - p0->z; 00271 m.u.m[2][1] = -praydir->y; 00272 m.u.m[3][1] = 0.0f; 00273 m.u.m[0][2] = p1->z - p0->z; 00274 m.u.m[1][2] = p2->z - p0->z; 00275 m.u.m[2][2] = -praydir->z; 00276 m.u.m[3][2] = 0.0f; 00277 m.u.m[0][3] = 0.0f; 00278 m.u.m[1][3] = 0.0f; 00279 m.u.m[2][3] = 0.0f; 00280 m.u.m[3][3] = 1.0f; 00281 00282 vec.x = praypos->x - p0->x; 00283 vec.y = praypos->y - p0->y; 00284 vec.z = praypos->z - p0->z; 00285 vec.w = 0.0f; 00286 00287 if ( D3DXMatrixInverse(&m, NULL, &m) ) 00288 { 00289 D3DXVec4Transform(&vec, &vec, &m); 00290 if ( (vec.x >= 0.0f) && (vec.y >= 0.0f) && (vec.x + vec.y <= 1.0f) && (vec.z >= 0.0f) ) 00291 { 00292 *pu = vec.x; 00293 *pv = vec.y; 00294 *pdist = fabs( vec.z ); 00295 return TRUE; 00296 } 00297 } 00298 00299 return FALSE; 00300 } 00301 00302 /************************************************************************* 00303 * D3DXSphereBoundProbe 00304 */ 00305 BOOL WINAPI D3DXSphereBoundProbe(CONST D3DXVECTOR3 *pcenter, FLOAT radius, CONST D3DXVECTOR3 *prayposition, CONST D3DXVECTOR3 *praydirection) 00306 { 00307 D3DXVECTOR3 difference; 00308 FLOAT a, b, c, d; 00309 00310 a = D3DXVec3LengthSq(praydirection); 00311 if (!D3DXVec3Subtract(&difference, prayposition, pcenter)) return FALSE; 00312 b = D3DXVec3Dot(&difference, praydirection); 00313 c = D3DXVec3LengthSq(&difference) - radius * radius; 00314 d = b * b - a * c; 00315 00316 if ( ( d <= 0.0f ) || ( sqrt(d) <= b ) ) return FALSE; 00317 return TRUE; 00318 } Generated on Sat May 26 2012 04:20:42 for ReactOS by
1.7.6.1
|