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
22 #include "wine/port.h"
23 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
30 /*************************************************************************
31 * D3DXComputeBoundingBox
33 HRESULT WINAPI
D3DXComputeBoundingBox(CONST D3DXVECTOR3
*pfirstposition
, DWORD numvertices
, DWORD dwstride
, D3DXVECTOR3
*pmin
, D3DXVECTOR3
*pmax
)
38 if( !pfirstposition
|| !pmin
|| !pmax
) return D3DERR_INVALIDCALL
;
40 *pmin
= *pfirstposition
;
43 for(i
=0; i
<numvertices
; i
++)
45 vec
= *( (D3DXVECTOR3
*)((char*)pfirstposition
+ dwstride
* i
) );
47 if ( vec
.x
< pmin
->x
) pmin
->x
= vec
.x
;
48 if ( vec
.x
> pmax
->x
) pmax
->x
= vec
.x
;
50 if ( vec
.y
< pmin
->y
) pmin
->y
= vec
.y
;
51 if ( vec
.y
> pmax
->y
) pmax
->y
= vec
.y
;
53 if ( vec
.z
< pmin
->z
) pmin
->z
= vec
.z
;
54 if ( vec
.z
> pmax
->z
) pmax
->z
= vec
.z
;
60 /*************************************************************************
61 * D3DXComputeBoundingSphere
63 HRESULT WINAPI
D3DXComputeBoundingSphere(CONST D3DXVECTOR3
* pfirstposition
, DWORD numvertices
, DWORD dwstride
, D3DXVECTOR3
*pcenter
, FLOAT
*pradius
)
65 D3DXVECTOR3 temp
, temp1
;
69 if( !pfirstposition
|| !pcenter
|| !pradius
) return D3DERR_INVALIDCALL
;
78 for(i
=0; i
<numvertices
; i
++)
80 D3DXVec3Add(&temp1
, &temp
, (D3DXVECTOR3
*)((char*)pfirstposition
+ dwstride
* i
));
84 D3DXVec3Scale(pcenter
, &temp
, 1.0f
/((FLOAT
)numvertices
));
86 for(i
=0; i
<numvertices
; i
++)
88 d
= D3DXVec3Length(D3DXVec3Subtract(&temp
, (D3DXVECTOR3
*)((char*)pfirstposition
+ dwstride
* i
), pcenter
));
89 if ( d
> *pradius
) *pradius
= d
;
94 /*************************************************************************
95 * D3DXGetFVFVertexSize
97 static UINT
Get_TexCoord_Size_From_FVF(DWORD FVF
, int tex_num
)
99 return (((((FVF
) >> (16 + (2 * (tex_num
)))) + 1) & 0x03) + 1);
102 UINT WINAPI
D3DXGetFVFVertexSize(DWORD FVF
)
106 UINT numTextures
= (FVF
& D3DFVF_TEXCOUNT_MASK
) >> D3DFVF_TEXCOUNT_SHIFT
;
108 if (FVF
& D3DFVF_NORMAL
) size
+= sizeof(D3DXVECTOR3
);
109 if (FVF
& D3DFVF_DIFFUSE
) size
+= sizeof(DWORD
);
110 if (FVF
& D3DFVF_SPECULAR
) size
+= sizeof(DWORD
);
111 if (FVF
& D3DFVF_PSIZE
) size
+= sizeof(DWORD
);
113 switch (FVF
& D3DFVF_POSITION_MASK
)
115 case D3DFVF_XYZ
: size
+= sizeof(D3DXVECTOR3
); break;
116 case D3DFVF_XYZRHW
: size
+= 4 * sizeof(FLOAT
); break;
117 case D3DFVF_XYZB1
: size
+= 4 * sizeof(FLOAT
); break;
118 case D3DFVF_XYZB2
: size
+= 5 * sizeof(FLOAT
); break;
119 case D3DFVF_XYZB3
: size
+= 6 * sizeof(FLOAT
); break;
120 case D3DFVF_XYZB4
: size
+= 7 * sizeof(FLOAT
); break;
121 case D3DFVF_XYZB5
: size
+= 8 * sizeof(FLOAT
); break;
122 case D3DFVF_XYZW
: size
+= 4 * sizeof(FLOAT
); break;
125 for (i
= 0; i
< numTextures
; i
++)
127 size
+= Get_TexCoord_Size_From_FVF(FVF
, i
) * sizeof(FLOAT
);
133 /*************************************************************************
134 * D3DXGetFVFVertexSize
136 UINT WINAPI
D3DXGetDeclVertexSize(const D3DVERTEXELEMENT9
*decl
, DWORD stream_idx
)
138 const D3DVERTEXELEMENT9
*element
;
141 TRACE("decl %p, stream_idx %u\n", decl
, stream_idx
);
145 for (element
= decl
; element
->Stream
!= 0xff; ++element
)
149 if (element
->Stream
!= stream_idx
) continue;
151 switch (element
->Type
)
153 case D3DDECLTYPE_FLOAT1
: type_size
= 1 * 4; break;
154 case D3DDECLTYPE_FLOAT2
: type_size
= 2 * 4; break;
155 case D3DDECLTYPE_FLOAT3
: type_size
= 3 * 4; break;
156 case D3DDECLTYPE_FLOAT4
: type_size
= 4 * 4; break;
157 case D3DDECLTYPE_D3DCOLOR
: type_size
= 4 * 1; break;
158 case D3DDECLTYPE_UBYTE4
: type_size
= 4 * 1; break;
159 case D3DDECLTYPE_SHORT2
: type_size
= 2 * 2; break;
160 case D3DDECLTYPE_SHORT4
: type_size
= 4 * 2; break;
161 case D3DDECLTYPE_UBYTE4N
: type_size
= 4 * 1; break;
162 case D3DDECLTYPE_SHORT2N
: type_size
= 2 * 2; break;
163 case D3DDECLTYPE_SHORT4N
: type_size
= 4 * 2; break;
164 case D3DDECLTYPE_USHORT2N
: type_size
= 2 * 2; break;
165 case D3DDECLTYPE_USHORT4N
: type_size
= 4 * 2; break;
166 case D3DDECLTYPE_UDEC3
: type_size
= 4; break; /* 3 * 10 bits + 2 padding */
167 case D3DDECLTYPE_DEC3N
: type_size
= 4; break;
168 case D3DDECLTYPE_FLOAT16_2
: type_size
= 2 * 2; break;
169 case D3DDECLTYPE_FLOAT16_4
: type_size
= 4 * 2; break;
171 FIXME("Unhandled element type %#x, size will be incorrect.\n", element
->Type
);
176 if (element
->Offset
+ type_size
> size
) size
= element
->Offset
+ type_size
;
182 /*************************************************************************
185 BOOL WINAPI
D3DXIntersectTri(CONST D3DXVECTOR3
*p0
, CONST D3DXVECTOR3
*p1
, CONST D3DXVECTOR3
*p2
, CONST D3DXVECTOR3
*praypos
, CONST D3DXVECTOR3
*praydir
, FLOAT
*pu
, FLOAT
*pv
, FLOAT
*pdist
)
190 m
.m
[0][0] = p1
->x
- p0
->x
;
191 m
.m
[1][0] = p2
->x
- p0
->x
;
192 m
.m
[2][0] = -praydir
->x
;
194 m
.m
[0][1] = p1
->y
- p0
->z
;
195 m
.m
[1][1] = p2
->y
- p0
->z
;
196 m
.m
[2][1] = -praydir
->y
;
198 m
.m
[0][2] = p1
->z
- p0
->z
;
199 m
.m
[1][2] = p2
->z
- p0
->z
;
200 m
.m
[2][2] = -praydir
->z
;
207 vec
.x
= praypos
->x
- p0
->x
;
208 vec
.y
= praypos
->y
- p0
->y
;
209 vec
.z
= praypos
->z
- p0
->z
;
212 if ( D3DXMatrixInverse(&m
, NULL
, &m
) )
214 D3DXVec4Transform(&vec
, &vec
, &m
);
215 if ( (vec
.x
>= 0.0f
) && (vec
.y
>= 0.0f
) && (vec
.x
+ vec
.y
<= 1.0f
) && (vec
.z
>= 0.0f
) )
219 *pdist
= fabs( vec
.z
);