101 iface->lpVtbl->AddRef(iface);
116 TRACE(
"%p increasing refcount to %u.\n",
mesh, refcount);
126 TRACE(
"%p decreasing refcount to %u.\n",
mesh, refcount);
132 if (
mesh->vertex_declaration)
151 TRACE(
"iface %p, attrib_id %u.\n", iface, attrib_id);
153 if (!
This->vertex_declaration)
155 WARN(
"Can't draw a mesh with an invalid vertex declaration.\n");
159 vertex_size = iface->lpVtbl->GetNumBytesPerVertex(iface);
170 for (face_start = face_end; face_start <
This->numfaces; face_start++)
172 if (
This->attrib_buffer[face_start] == attrib_id)
175 if (face_start >=
This->numfaces)
177 for (face_end = face_start + 1; face_end <
This->numfaces; face_end++)
179 if (
This->attrib_buffer[face_end] != attrib_id)
184 0, 0,
This->numvertices, face_start * 3, face_end - face_start);
195 TRACE(
"iface %p.\n", iface);
197 return mesh->numfaces;
204 TRACE(
"iface %p.\n", iface);
206 return mesh->numvertices;
213 TRACE(
"iface %p.\n", iface);
241 TRACE(
"iface %p.\n", iface);
243 return mesh->vertex_declaration_size;
250 TRACE(
"iface %p.\n", iface);
252 return mesh->options;
270 struct IDirect3DDevice9 *
device,
struct ID3DXMesh **clone_mesh)
275 TRACE(
"iface %p, options %#x, fvf %#x, device %p, clone_mesh %p.\n",
464 FIXME(
"Conversion from D3DDECLTYPE_FLOAT4 to %d not implemented.\n", type_dst);
478 D3DXVECTOR4 src_float4 = {*src_ptr, 0.0f, 0.0f, 1.0f};
485 D3DXVECTOR4 src_float4 = {src_ptr->
x, src_ptr->
y, 0.0f, 1.0f};
492 D3DXVECTOR4 src_float4 = {src_ptr->
x, src_ptr->
y, src_ptr->
z, 1.0f};
499 D3DXVECTOR4 src_float4 = {src_ptr->
x, src_ptr->
y, src_ptr->
z, src_ptr->
w};
524 D3DXVECTOR4 src_float4 = {src_ptr[0], src_ptr[1], 0.0f, 1.0f};
531 D3DXVECTOR4 src_float4 = {src_ptr[0], src_ptr[1], src_ptr[2], src_ptr[3]};
583 FIXME(
"Conversion of D3DDECLTYPE %d to %d not implemented.\n", type_src, type_dst);
612 UINT num_vertices = mesh_src->lpVtbl->GetNumVertices(mesh_src);
613 UINT dst_vertex_size = mesh_dst->lpVtbl->GetNumBytesPerVertex(mesh_dst);
614 UINT src_vertex_size = mesh_src->lpVtbl->GetNumBytesPerVertex(mesh_src);
616 hr = mesh_src->lpVtbl->GetDeclaration(mesh_src, orig_declaration);
618 hr = mesh_dst->lpVtbl->GetDeclaration(mesh_dst,
declaration);
623 hr = mesh_dst->lpVtbl->LockVertexBuffer(mesh_dst, 0, (
void**)&vb_dst);
627 memset(vb_dst, 0, num_vertices * dst_vertex_size);
629 for (
i = 0; orig_declaration[
i].
Stream != 0xff;
i++)
636 for (
j = 0;
j < num_vertices;
j++)
639 UINT idx_src = src_vertex_size *
j + orig_declaration[
i].
Offset;
643 memcpy(&vb_dst[idx_dst], &vb_src[idx_src], type_size);
652 if (vb_dst) mesh_dst->lpVtbl->UnlockVertexBuffer(mesh_dst);
653 if (vb_src) mesh_src->lpVtbl->UnlockVertexBuffer(mesh_src);
660 UINT size1 = 0, size2 = 0;
663 while (declaration1[size1].
Stream != 0xff) size1++;
664 while (declaration2[size2].
Stream != 0xff) size2++;
671 if (
memcmp(declaration1, declaration2, size1*
sizeof(*declaration1)) == 0)
682 ID3DXMesh *clone_mesh;
684 void *data_in, *data_out;
687 BOOL same_declaration;
689 TRACE(
"iface %p, options %#x, declaration %p, device %p, clone_mesh_out %p.\n",
695 hr = iface->lpVtbl->GetDeclaration(iface, orig_declaration);
703 vertex_size = clone_mesh->lpVtbl->GetNumBytesPerVertex(clone_mesh);
707 if (!same_declaration) {
715 }
else if (same_declaration) {
718 hr = clone_mesh->lpVtbl->LockVertexBuffer(clone_mesh, 0, &data_out);
720 iface->lpVtbl->UnlockVertexBuffer(iface);
723 memcpy(data_out, data_in,
This->numvertices * vertex_size);
724 clone_mesh->lpVtbl->UnlockVertexBuffer(clone_mesh);
725 iface->lpVtbl->UnlockVertexBuffer(iface);
733 hr = clone_mesh->lpVtbl->LockIndexBuffer(clone_mesh, 0, &data_out);
735 iface->lpVtbl->UnlockIndexBuffer(iface);
741 for (
i = 0;
i <
This->numfaces * 3;
i++)
744 for (
i = 0;
i <
This->numfaces * 3;
i++)
750 clone_mesh->lpVtbl->UnlockIndexBuffer(clone_mesh);
751 iface->lpVtbl->UnlockIndexBuffer(iface);
755 if (
This->attrib_table_size)
766 *clone_mesh_out = clone_mesh;
770 IUnknown_Release(clone_mesh);
817 TRACE(
"iface %p.\n", iface);
835 TRACE(
"iface %p.\n", iface);
847 TRACE(
"iface %p, attrib_table %p, attrib_table_size %p.\n",
896 for (
i = 0;
i < 3 * num_faces;
i++)
903 for (edge = 0; edge < 3; edge++)
929 if (edge_face_ptr->
v2 == vertex1)
930 return edge_face_ptr->
face;
938 DWORD *id_point_reps;
945 for (
i = 0;
i < num_vertices;
i++)
947 id_point_reps[
i] =
i;
950 return id_point_reps;
957 DWORD num_faces = iface->lpVtbl->GetNumFaces(iface);
958 DWORD num_vertices = iface->lpVtbl->GetNumVertices(iface);
969 TRACE(
"iface %p, point_reps %p, adjacency %p.\n", iface, point_reps, adjacency);
982 point_reps_ptr = id_point_reps;
986 point_reps_ptr = point_reps;
992 if (indices_are_16_bit)
996 WORD *ib_16bit = ib_ptr;
1003 for (
i = 0;
i < 3 * num_faces;
i++)
1005 ib[
i] = ib_16bit[
i];
1019 for (edge = 0; edge < 3; edge++)
1023 DWORD new_v1 = point_reps_ptr[
v1];
1024 DWORD new_v2 = point_reps_ptr[
v2];
1028 adjacency[3*
face + edge] = adj_face;
1038 if(ib_ptr) iface->lpVtbl->UnlockIndexBuffer(iface);
1057 const unsigned int VERTS_PER_FACE = 3;
1058 DWORD edge, opp_edge;
1059 DWORD face_base = VERTS_PER_FACE *
face;
1061 for (edge = 0; edge < VERTS_PER_FACE; edge++)
1063 DWORD adj_face = adjacency[face_base + edge];
1064 DWORD adj_face_base;
1068 else if (adj_face >= numfaces)
1071 WARN(
"Index out of bounds. Got %d expected less than %d.\n",
1072 adj_face, numfaces);
1075 adj_face_base = 3 * adj_face;
1078 for (opp_edge = 0; opp_edge < VERTS_PER_FACE; opp_edge++)
1080 DWORD opp_edge_index = adj_face_base + opp_edge;
1081 if (adjacency[opp_edge_index] ==
face)
1086 for (
i = 0;
i < 2;
i++)
1088 DWORD from = face_base + (edge + (1 -
i)) % VERTS_PER_FACE;
1089 DWORD to = adj_face_base + (opp_edge +
i) % VERTS_PER_FACE;
1092 if (new_indices[to] > new_indices[
from])
1094 new_indices[to] = new_indices[
from];
1113 const unsigned int VERTS_PER_FACE = 3;
1115 TRACE(
"iface %p, adjacency %p, point_reps %p.\n", iface, adjacency, point_reps);
1119 WARN(
"NULL adjacency.\n");
1126 WARN(
"NULL point_reps.\n");
1132 if (
This->numfaces == 0)
1134 ERR(
"Number of faces was zero.\n");
1156 hr = iface->lpVtbl->LockIndexBuffer(iface,
D3DLOCK_READONLY, (
void**)&indices_16bit);
1164 for (
i = 0;
i < VERTS_PER_FACE *
This->numfaces;
i++)
1166 new_indices[
i] = indices_16bit[
i];
1172 for (
i = 0;
i <
This->numvertices;
i++)
1198 if (
indices) iface->lpVtbl->UnlockIndexBuffer(iface);
1202 if (indices_16bit) iface->lpVtbl->UnlockIndexBuffer(iface);
1237 const FLOAT epsilon_sq = epsilon * epsilon;
1240 TRACE(
"iface %p, epsilon %.8e, adjacency %p.\n", iface, epsilon, adjacency);
1245 buffer_size =
This->numfaces * 3 *
sizeof(*shared_indices) +
This->numvertices *
sizeof(*sorted_vertices);
1249 if (!shared_indices)
1260 DWORD *dword_indices = (
DWORD*)(sorted_vertices +
This->numvertices);
1262 for (
i = 0;
i <
This->numfaces * 3;
i++)
1263 *dword_indices++ = *word_indices++;
1266 vertex_size = iface->lpVtbl->GetNumBytesPerVertex(iface);
1267 for (
i = 0;
i <
This->numvertices;
i++) {
1273 for (
i = 0;
i <
This->numfaces * 3;
i++) {
1281 for (
i = 0;
i <
This->numvertices;
i++) {
1286 while (shared_index_a != -1) {
1288 DWORD shared_index_b = shared_indices[shared_index_a];
1292 while (shared_index_b != -1) {
1294 DWORD base_a = (shared_index_a / 3) * 3;
1295 DWORD base_b = (shared_index_b / 3) * 3;
1299 for (
k = 0;
k < 3;
k++) {
1300 if (adjacency[base_b +
k] == shared_index_a / 3) {
1306 for (
k = 1;
k <= 2;
k++) {
1307 DWORD vertex_index_a = base_a + (shared_index_a +
k) % 3;
1308 DWORD vertex_index_b = base_b + (shared_index_b + (3 -
k)) % 3;
1310 if (!adjacent && epsilon >= 0.0f) {
1314 D3DXVec3Subtract(&delta,
1317 length_sq = D3DXVec3LengthSq(&delta);
1318 adjacent = epsilon == 0.0f ? length_sq == 0.0f : length_sq < epsilon_sq;
1321 DWORD adj_a = base_a + 2 - (vertex_index_a + shared_index_a + 1) % 3;
1322 DWORD adj_b = base_b + 2 - (vertex_index_b + shared_index_b + 1) % 3;
1323 if (adjacency[adj_a] == -1 && adjacency[adj_b] == -1) {
1324 adjacency[adj_a] = base_b / 3;
1325 adjacency[adj_b] = base_a / 3;
1332 shared_index_b = shared_indices[shared_index_b];
1334 while (++j < This->numvertices) {
1338 if (sorted_vertex_b->
key - sorted_vertex_a->
key > epsilon * 3.0f) {
1340 j =
This->numvertices;
1345 if (
fabsf(vertex_a->
x - vertex_b->
x) <= epsilon &&
1346 fabsf(vertex_a->
y - vertex_b->
y) <= epsilon &&
1347 fabsf(vertex_a->
z - vertex_b->
z) <= epsilon)
1352 if (
j >=
This->numvertices)
1364 if (
indices) iface->lpVtbl->UnlockIndexBuffer(iface);
1365 if (vertices) iface->lpVtbl->UnlockVertexBuffer(iface);
1381 WARN(
"Invalid declaration. Can't use NULL declaration.\n");
1389 WARN(
"Invalid declaration. New vertex size does not match the original vertex size.\n");
1398 WARN(
"Invalid declaration. New declaration contains non-zero Stream value.\n");
1403 This->num_elem =
i + 1;
1406 if (
This->vertex_declaration)
1419 &
This->vertex_declaration);
1422 WARN(
"Using invalid declaration. Calls to DrawSubset will fail.\n");
1440 mesh->attrib_table_size = 0;
1455 TRACE(
"iface %p.\n", iface);
1473 ID3DXMesh *optimized_mesh;
1475 TRACE(
"iface %p, flags %#x, adjacency_in %p, adjacency_out %p, face_remap %p, vertex_remap %p, opt_mesh %p.\n",
1476 iface,
flags, adjacency_in, adjacency_out, face_remap, vertex_remap, opt_mesh);
1487 hr = optimized_mesh->lpVtbl->OptimizeInplace(optimized_mesh,
flags, adjacency_in, adjacency_out, face_remap, vertex_remap);
1489 *opt_mesh = optimized_mesh;
1491 IUnknown_Release(optimized_mesh);
1501 DWORD *vertex_remap_ptr;
1502 DWORD num_used_vertices;
1509 for (
i = 0;
i <
This->numfaces * 3;
i++)
1513 num_used_vertices = 0;
1514 for (
i = 0;
i <
This->numvertices;
i++) {
1515 if (vertex_remap_ptr[
i])
1516 vertex_remap_ptr[
i] = num_used_vertices++;
1518 vertex_remap_ptr[
i] = -1;
1521 for (
i = 0;
i <
This->numfaces * 3;
i++)
1525 num_used_vertices = 0;
1526 for (
i = 0;
i <
This->numvertices;
i++) {
1527 if (vertex_remap_ptr[
i] != -1)
1528 vertex_remap_ptr[num_used_vertices++] =
i;
1530 for (
i = num_used_vertices;
i <
This->numvertices;
i++)
1531 vertex_remap_ptr[
i] = -1;
1533 *new_num_vertices = num_used_vertices;
1558 DWORD min_vertex, max_vertex;
1563 min_vertex = (
DWORD)-1;
1576 min_vertex = (
DWORD)-1;
1579 for (
j = 0;
j < 3;
j++) {
1597 int delta = *ptr_a - *ptr_b;
1602 delta = ptr_a - ptr_b;
1610 DWORD **sorted_attrib_ptr_buffer =
NULL;
1614 if (!sorted_attrib_ptr_buffer)
1624 for (
i = 0;
i <
This->numfaces;
i++)
1628 for (
i = 0;
i <
This->numfaces;
i++)
1631 (*face_remap)[old_face] =
i;
1635 *sorted_attrib_buffer = (
DWORD*)sorted_attrib_ptr_buffer;
1636 for (
i = 0;
i <
This->numfaces;
i++)
1652 DWORD new_num_vertices = 0;
1653 DWORD new_num_alloc_vertices = 0;
1658 TRACE(
"iface %p, flags %#x, adjacency_in %p, adjacency_out %p, face_remap_out %p, vertex_remap_out %p.\n",
1659 iface,
flags, adjacency_in, adjacency_out, face_remap_out, vertex_remap_out);
1671 FIXME(
"D3DXMESHOPT_VERTEXCACHE not implemented.\n");
1673 FIXME(
"D3DXMESHOPT_STRIPREORDER not implemented.\n");
1677 hr = iface->lpVtbl->LockIndexBuffer(iface, 0, &
indices);
1686 for (
i = 0;
i <
This->numfaces * 3;
i++)
1687 dword_indices[
i] = *word_indices++;
1692 new_num_alloc_vertices =
This->numvertices;
1697 FIXME(
"D3DXMESHOPT_ATTRSORT vertex reordering not implemented.\n");
1711 DWORD vertex_size = iface->lpVtbl->GetNumBytesPerVertex(iface);
1712 BYTE *orig_vertices;
1731 for (
i = 0;
i < new_num_vertices;
i++)
1732 memcpy(new_vertices +
i * vertex_size, orig_vertices + vertex_remap_ptr[
i] * vertex_size, vertex_size);
1736 }
else if (vertex_remap_out) {
1737 DWORD *vertex_remap_ptr;
1742 for (
i = 0;
i <
This->numvertices;
i++)
1743 *vertex_remap_ptr++ =
i;
1762 for (
i = 0;
i <
This->numfaces;
i++)
1766 for (
i = 0;
i <
This->numfaces;
i++) {
1767 DWORD new_pos = face_remap[
i] * 3;
1769 word_indices[new_pos++] = dword_indices[old_pos++];
1770 word_indices[new_pos++] = dword_indices[old_pos++];
1771 word_indices[new_pos] = dword_indices[old_pos];
1786 for (
i = 0;
i <
This->numfaces * 3;
i++)
1787 *word_indices++ = dword_indices[
i];
1791 if (adjacency_out) {
1793 for (
i = 0;
i <
This->numfaces;
i++) {
1795 DWORD new_pos = face_remap[
i] * 3;
1796 adjacency_out[new_pos++] = face_remap[adjacency_in[old_pos++]];
1797 adjacency_out[new_pos++] = face_remap[adjacency_in[old_pos++]];
1798 adjacency_out[new_pos++] = face_remap[adjacency_in[old_pos++]];
1801 memcpy(adjacency_out, adjacency_in,
This->numfaces * 3 *
sizeof(*adjacency_out));
1804 if (face_remap_out) {
1806 for (
i = 0;
i <
This->numfaces;
i++)
1807 face_remap_out[face_remap[
i]] =
i;
1809 for (
i = 0;
i <
This->numfaces;
i++)
1810 face_remap_out[
i] =
i;
1813 if (vertex_remap_out)
1814 *vertex_remap_out = vertex_remap;
1815 vertex_remap =
NULL;
1821 This->numvertices = new_num_vertices;
1831 if (
attrib_buffer) iface->lpVtbl->UnlockAttributeBuffer(iface);
1832 if (
indices) iface->lpVtbl->UnlockIndexBuffer(iface);
1856 mesh->attrib_table = new_table;
1914 FLOAT div, tmin, tmax, tymin, tymax, tzmin, tzmax;
1916 div = 1.0f / praydirection->
x;
1919 tmin = ( pmin->
x - prayposition->
x ) *
div;
1920 tmax = ( pmax->
x - prayposition->
x ) *
div;
1924 tmin = ( pmax->
x - prayposition->
x ) *
div;
1925 tmax = ( pmin->
x - prayposition->
x ) *
div;
1928 if ( tmax < 0.0f )
return FALSE;
1930 div = 1.0f / praydirection->
y;
1933 tymin = ( pmin->
y - prayposition->
y ) *
div;
1934 tymax = ( pmax->
y - prayposition->
y ) *
div;
1938 tymin = ( pmax->
y - prayposition->
y ) *
div;
1939 tymax = ( pmin->
y - prayposition->
y ) *
div;
1942 if ( ( tymax < 0.0f ) || ( tmin > tymax ) || ( tymin > tmax ) )
return FALSE;
1944 if ( tymin > tmin ) tmin = tymin;
1945 if ( tymax < tmax ) tmax = tymax;
1947 div = 1.0f / praydirection->
z;
1950 tzmin = ( pmin->
z - prayposition->
z ) *
div;
1951 tzmax = ( pmax->
z - prayposition->
z ) *
div;
1955 tzmin = ( pmax->
z - prayposition->
z ) *
div;
1956 tzmax = ( pmin->
z - prayposition->
z ) *
div;
1959 if ( (tzmax < 0.0f ) || ( tmin > tzmax ) || ( tzmin > tmax ) )
return FALSE;
1972 *pmin = *pfirstposition;
1975 for(
i=0;
i<numvertices;
i++)
1977 vec = *( (
const D3DXVECTOR3*)((
const char*)pfirstposition + dwstride *
i) );
1985 if (
vec.z < pmin->
z ) pmin->
z =
vec.z;
1986 if (
vec.z > pmax->
z ) pmax->
z =
vec.z;
2006 for(
i=0;
i<numvertices;
i++)
2009 D3DXVec3Scale(pcenter, &
temp, 1.0f / numvertices);
2011 for(
i=0;
i<numvertices;
i++)
2013 d = D3DXVec3Length(D3DXVec3Subtract(&
temp, (
const D3DXVECTOR3*)((
const char*)pfirstposition + dwstride *
i), pcenter));
2014 if (
d > *pradius ) *pradius =
d;
2041 unsigned int idx = 0;
2054 if (has_blend_idx) --blend_count;
2057 || (has_blend && blend_count > 4))
2067 switch (blend_count)
2084 ERR(
"Invalid blend count %u.\n", blend_count);
2107 for (
i = 0;
i < tex_count; ++
i)
2109 switch ((fvf >> (16 + 2 *
i)) & 0x03)
2286 return (((((FVF) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1);
2312 for (
i = 0;
i < numTextures;
i++)
2328 TRACE(
"decl %p, stream_idx %u\n", decl, stream_idx);
2330 if (!decl)
return 0;
2336 if (
element->Stream != stream_idx)
continue;
2340 FIXME(
"Unhandled element type %#x, size will be incorrect.\n",
element->Type);
2358 TRACE(
"decl %p\n", decl);
2373 TRACE(
"p0 %p, p1 %p, p2 %p, praypos %p, praydir %p, pu %p, pv %p, pdist %p.\n",
2374 p0, p1, p2, praypos, praydir, pu, pv, pdist);
2376 m.u.m[0][0] = p1->
x - p0->
x;
2377 m.u.m[1][0] = p2->
x - p0->
x;
2378 m.u.m[2][0] = -praydir->
x;
2380 m.u.m[0][1] = p1->
y - p0->
y;
2381 m.u.m[1][1] = p2->
y - p0->
y;
2382 m.u.m[2][1] = -praydir->
y;
2384 m.u.m[0][2] = p1->
z - p0->
z;
2385 m.u.m[1][2] = p2->
z - p0->
z;
2386 m.u.m[2][2] = -praydir->
z;
2393 vec.
x = praypos->
x - p0->
x;
2394 vec.
y = praypos->
y - p0->
y;
2395 vec.z = praypos->
z - p0->
z;
2403 if (pu) *pu =
vec.
x;
2404 if (pv) *pv =
vec.
y;
2405 if (pdist) *pdist =
fabsf(
vec.z );
2419 D3DXVec3Subtract(&difference, ray_position, center);
2420 c = D3DXVec3LengthSq(&difference) - radius * radius;
2423 a = D3DXVec3LengthSq(ray_direction);
2424 b = D3DXVec3Dot(&difference, ray_direction);
2427 return d >= 0.0f && (
b <= 0.0f ||
d >
b *
b);
2438 IDirect3DVertexDeclaration9 *vertex_declaration;
2439 UINT vertex_declaration_size;
2442 IDirect3DIndexBuffer9 *index_buffer;
2443 DWORD *attrib_buffer;
2445 DWORD index_usage = 0;
2448 DWORD vertex_usage = 0;
2452 TRACE(
"numfaces %u, numvertices %u, options %#x, declaration %p, device %p, mesh %p.\n",
2522 WARN(
"Unexpected return value %x from IDirect3DDevice9_CreateVertexDeclaration.\n",
hr);
2537 WARN(
"Unexpected return value %x from IDirect3DDevice9_CreateVertexBuffer.\n",
hr);
2552 WARN(
"Unexpected return value %x from IDirect3DDevice9_CreateVertexBuffer.\n",
hr);
2588 *
mesh = &
object->ID3DXMesh_iface;
2602 TRACE(
"(%u, %u, %u, %u, %p, %p)\n",
numfaces,
numvertices,
options,
fvf,
device,
mesh);
2653 *filename_out =
NULL;
2655 hr = filedata->lpVtbl->Lock(filedata, &data_size, (
const void**)&
data);
2659 if (data_size <
sizeof(filename_in))
2661 WARN(
"truncated data (%lu bytes)\n", data_size);
2662 filedata->lpVtbl->Unlock(filedata);
2665 filename_in = *(
char **)
data;
2669 filedata->lpVtbl->Unlock(filedata);
2676 filedata->lpVtbl->Unlock(filedata);
2687 ID3DXFileData *
child;
2692 hr = filedata->lpVtbl->Lock(filedata, &data_size, (
const void**)&
data);
2715 if (data_size !=
sizeof(
FLOAT) * 11) {
2716 WARN(
"incorrect data size (%ld bytes)\n", data_size);
2717 filedata->lpVtbl->Unlock(filedata);
2735 filedata->lpVtbl->Unlock(filedata);
2737 hr = filedata->lpVtbl->GetChildren(filedata, &nb_children);
2741 for (
i = 0;
i < nb_children;
i++)
2743 hr = filedata->lpVtbl->GetChild(filedata,
i, &
child);
2755 IUnknown_Release(
child);
2760 IUnknown_Release(
child);
2767 for (
i = 0;
i <
mesh->num_materials;
i++)
2771 mesh->num_materials = 0;
2783 DWORD num_materials;
2789 hr = filedata->lpVtbl->Lock(filedata, &data_size, (
const void**)&
data);
2803 if (data_size <
sizeof(
DWORD)) {
2804 WARN(
"truncated data (%ld bytes)\n", data_size);
2807 num_materials = *in_ptr++;
2808 if (!num_materials) {
2813 if (data_size < 2 *
sizeof(
DWORD)) {
2814 WARN(
"truncated data (%ld bytes)\n", data_size);
2817 if (*in_ptr++ !=
mesh->num_poly_faces) {
2818 WARN(
"number of material face indices (%u) doesn't match number of faces (%u)\n",
2819 *(in_ptr - 1),
mesh->num_poly_faces);
2822 if (data_size < 2 *
sizeof(
DWORD) +
mesh->num_poly_faces *
sizeof(
DWORD)) {
2823 WARN(
"truncated data (%ld bytes)\n", data_size);
2826 for (
i = 0;
i <
mesh->num_poly_faces;
i++) {
2827 if (*in_ptr++ >= num_materials) {
2828 WARN(
"face %u: reference to undefined material %u (only %u materials)\n",
2829 i, *(in_ptr - 1), num_materials);
2836 if (!
mesh->materials || !
mesh->material_indices) {
2842 hr = filedata->lpVtbl->GetChildren(filedata, &nb_children);
2846 for (
i = 0;
i < nb_children;
i++)
2848 hr = filedata->lpVtbl->GetChild(filedata,
i, &
child);
2856 if (
mesh->num_materials >= num_materials) {
2857 WARN(
"more materials defined than declared\n");
2866 IUnknown_Release(
child);
2869 if (num_materials !=
mesh->num_materials) {
2870 WARN(
"only %u of %u materials defined\n", num_materials,
mesh->num_materials);
2876 IUnknown_Release(
child);
2877 filedata->lpVtbl->Unlock(filedata);
2890 hr = filedata->lpVtbl->Lock(filedata, &data_size, (
const void**)&
data);
2905 if (data_size <
sizeof(
DWORD)) {
2906 WARN(
"truncated data (%ld bytes)\n", data_size);
2910 WARN(
"number of texture coordinates (%u) doesn't match number of vertices (%u)\n",
2915 if (data_size <
sizeof(
DWORD) +
mesh->num_vertices *
sizeof(*
mesh->tex_coords)) {
2916 WARN(
"truncated data (%ld bytes)\n", data_size);
2921 if (!
mesh->tex_coords) {
2932 filedata->lpVtbl->Unlock(filedata);
2947 hr = filedata->lpVtbl->Lock(filedata, &data_size, (
const void**)&
data);
2962 if (data_size <
sizeof(
DWORD)) {
2963 WARN(
"truncated data (%ld bytes)\n", data_size);
2969 WARN(
"truncated data (%ld bytes)\n", data_size);
2974 if (!
mesh->vertex_colors) {
2979 for (
i = 0;
i <
mesh->num_vertices;
i++)
2981 for (
i = 0;
i < num_colors;
i++)
2987 WARN(
"vertex color %u references undefined vertex %u (only %u vertices)\n",
3008 filedata->lpVtbl->Unlock(filedata);
3017 DWORD *index_out_ptr;
3019 DWORD num_face_indices =
mesh->num_poly_faces * 2 +
mesh->num_tri_faces;
3022 mesh->num_normals = 0;
3027 hr = filedata->lpVtbl->Lock(filedata, &data_size, (
const void**)&
data);
3049 if (data_size <
sizeof(
DWORD) * 2) {
3050 WARN(
"truncated data (%ld bytes)\n", data_size);
3056 num_face_indices *
sizeof(
DWORD)) {
3057 WARN(
"truncated data (%ld bytes)\n", data_size);
3063 if (!
mesh->normals || !
mesh->normal_indices) {
3070 for (
i = 0;
i <
mesh->num_normals;
i++)
3074 WARN(
"number of face normals (%u) doesn't match number of faces (%u)\n",
3079 index_out_ptr =
mesh->normal_indices;
3080 for (
i = 0;
i <
mesh->num_poly_faces;
i++)
3084 if (
count !=
mesh->num_tri_per_face[
i] + 2) {
3085 WARN(
"face %u: number of normals (%u) doesn't match number of vertices (%u)\n",
3093 if (normal_index >=
mesh->num_normals) {
3094 WARN(
"face %u, normal index %u: reference to undefined normal %u (only %u normals)\n",
3095 i,
j, normal_index,
mesh->num_normals);
3098 *index_out_ptr++ = normal_index;
3106 filedata->lpVtbl->Unlock(filedata);
3118 hr = filedata->lpVtbl->Lock(filedata, &data_size, (
const void**)&
data);
3124 if (data_size <
sizeof(
WORD) * 3) {
3125 WARN(
"truncated data (%ld bytes)\n", data_size);
3134 DWORD nb_influences;
3138 data +=
sizeof(
char*);
3143 if (data_size < (
sizeof(
char*) +
sizeof(
DWORD) + nb_influences * (
sizeof(
DWORD) +
sizeof(
FLOAT)) + 16 *
sizeof(
FLOAT))) {
3144 WARN(
"truncated data (%ld bytes)\n", data_size);
3158 filedata->lpVtbl->Unlock(filedata);
3163#define PROVIDE_MATERIALS 0x1
3164#define PROVIDE_SKININFO 0x2
3165#define PROVIDE_ADJACENCY 0x4
3172 DWORD *index_out_ptr;
3177 DWORD nb_skin_weights_info = 0;
3189 hr = filedata->lpVtbl->Lock(filedata, &data_size, (
const void**)&
data);
3195 if (data_size <
sizeof(
DWORD) * 2) {
3196 WARN(
"truncated data (%ld bytes)\n", data_size);
3201 WARN(
"truncated data (%ld bytes)\n", data_size);
3207 in_ptr +=
sizeof(
DWORD);
3212 DWORD num_poly_vertices;
3215 if (data_size - (in_ptr -
data) <
sizeof(
DWORD)) {
3216 WARN(
"truncated data (%ld bytes)\n", data_size);
3219 num_poly_vertices = *(
DWORD*)in_ptr;
3220 in_ptr +=
sizeof(
DWORD);
3221 if (data_size - (in_ptr -
data) < num_poly_vertices *
sizeof(
DWORD)) {
3222 WARN(
"truncated data (%ld bytes)\n", data_size);
3225 if (num_poly_vertices < 3) {
3226 WARN(
"face %u has only %u vertices\n",
i, num_poly_vertices);
3229 for (
j = 0;
j < num_poly_vertices;
j++) {
3231 WARN(
"face %u, index %u: undefined vertex %u (only %u vertices)\n",
3235 in_ptr +=
sizeof(
DWORD);
3263 in_ptr +=
sizeof(
DWORD);
3267 *index_out_ptr++ = *(
DWORD*)in_ptr;
3268 in_ptr +=
sizeof(
DWORD);
3272 hr = filedata->lpVtbl->GetChildren(filedata, &nb_children);
3276 for (
i = 0;
i < nb_children;
i++)
3278 hr = filedata->lpVtbl->GetChild(filedata,
i, &
child);
3298 WARN(
"Skin mesh header already encountered\n");
3307 WARN(
"Skin weights found but skin mesh header not encountered yet\n");
3314 nb_skin_weights_info++;
3320 IUnknown_Release(
child);
3325 WARN(
"Mismatch between nb skin weights info %u encountered and nb bones %u from skin mesh header\n",
3342 IUnknown_Release(
child);
3343 filedata->lpVtbl->Unlock(filedata);
3354 static const struct {
3355 const char *param_name;
3359 } material_effects[] = {
3360#define EFFECT_TABLE_ENTRY(str, field) \
3361 {str, sizeof(str), sizeof(material_ptr->MatD3D.field), offsetof(D3DXMATERIAL, MatD3D.field)}
3367#undef EFFECT_TABLE_ENTRY
3369 static const char texture_paramname[] =
"Texture0@Name";
3393 for (
i = 0;
i < num_materials;
i++) {
3394 if (material_ptr[
i].pTextureFilename) {
3404 out_ptr = (
BYTE*)(effect_ptr + num_materials);
3406 for (
i = 0;
i < num_materials;
i++)
3417 defaults->pParamName = (
char *)out_ptr;
3421 defaults->NumBytes = material_effects[
j].num_bytes;
3429 defaults->pParamName = (
char *)out_ptr;
3447 struct ID3DXBuffer **effects_out,
DWORD *num_materials_out,
struct ID3DXSkinInfo **skin_info_out,
3448 struct ID3DXMesh **mesh_out)
3451 DWORD *index_in_ptr;
3453 DWORD total_vertices;
3454 ID3DXMesh *d3dxmesh =
NULL;
3458 struct vertex_duplication {
3461 } *duplications =
NULL;
3463 void *vertices =
NULL;
3466 DWORD provide_flags = 0;
3468 TRACE(
"(%p, %x, %p, %p, %p, %p, %p, %p, %p)\n", filedata,
options,
device, adjacency_out, materials_out,
3469 effects_out, num_materials_out, skin_info_out, mesh_out);
3473 if (num_materials_out || materials_out || effects_out)
3486 if (!duplications) {
3490 for (
i = 0;
i < total_vertices;
i++)
3492 duplications[
i].normal_index = -1;
3495 for (
i = 0;
i < num_face_indices;
i++) {
3498 struct vertex_duplication *dup_ptr = &duplications[
vertex_index];
3500 if (dup_ptr->normal_index == -1) {
3501 dup_ptr->normal_index = normal_index;
3504 struct list *dup_list = &dup_ptr->entry;
3507 if (new_normal->
x == cur_normal->
x &&
3508 new_normal->
y == cur_normal->
y &&
3509 new_normal->
z == cur_normal->
z)
3513 }
else if (!
list_next(dup_list, &dup_ptr->entry)) {
3514 dup_ptr = &duplications[total_vertices++];
3515 dup_ptr->normal_index = normal_index;
3521 struct vertex_duplication,
entry);
3531 hr = d3dxmesh->lpVtbl->LockVertexBuffer(d3dxmesh, 0, &vertices);
3539 if (duplications[
i].normal_index == -1)
3547 out_ptr +=
sizeof(
DWORD);
3558 struct vertex_duplication *dup_ptr;
3561 int j = dup_ptr - duplications;
3562 BYTE *dest_vertex = (
BYTE*)vertices +
j * vertex_size;
3564 memcpy(dest_vertex, out_ptr, vertex_size);
3568 out_ptr += vertex_size;
3571 d3dxmesh->lpVtbl->UnlockVertexBuffer(d3dxmesh);
3573 hr = d3dxmesh->lpVtbl->LockIndexBuffer(d3dxmesh, 0, &
indices);
3577#define FILL_INDEX_BUFFER(indices_var) \
3578 for (i = 0; i < mesh_data.num_poly_faces; i++) \
3580 DWORD count = mesh_data.num_tri_per_face[i]; \
3581 WORD first_index = *index_in_ptr++; \
3583 *indices_var++ = first_index; \
3584 *indices_var++ = *index_in_ptr; \
3586 *indices_var++ = *index_in_ptr; \
3597#undef FILL_INDEX_BUFFER
3598 d3dxmesh->lpVtbl->UnlockIndexBuffer(d3dxmesh);
3602 hr = d3dxmesh->lpVtbl->LockAttributeBuffer(d3dxmesh, 0, &attrib_buffer);
3610 d3dxmesh->lpVtbl->UnlockAttributeBuffer(d3dxmesh);
3612 hr = d3dxmesh->lpVtbl->OptimizeInplace(d3dxmesh,
3620 char *strings_out_ptr;
3635 if (materials_ptr[
i].pTextureFilename) {
3647 if (!materials_out) {
3653 if (adjacency_out) {
3660 *mesh_out = d3dxmesh;
3661 if (adjacency_out) *adjacency_out = adjacency;
3663 if (materials_out) *materials_out = materials;
3664 if (effects_out) *effects_out = effects;
3670 if (d3dxmesh) IUnknown_Release(d3dxmesh);
3675 if (skin_info_out) *skin_info_out =
NULL;
3690 struct ID3DXAllocateHierarchy *
alloc_hier,
struct ID3DXLoadUserData *load_user_data,
3691 D3DXFRAME **frame_hierarchy,
struct ID3DXAnimationController **anim_controller)
3697 TRACE(
"filename %s, options %#x, device %p, alloc_hier %p, "
3698 "load_user_data %p, frame_hierarchy %p, anim_controller %p.\n",
3700 load_user_data, frame_hierarchy, anim_controller);
3711 alloc_hier, load_user_data, frame_hierarchy, anim_controller);
3718 struct ID3DXAllocateHierarchy *
alloc_hier,
struct ID3DXLoadUserData *load_user_data,
3719 D3DXFRAME **frame_hierarchy,
struct ID3DXAnimationController **anim_controller)
3725 TRACE(
"filename %s, options %#x, device %p, alloc_hier %p, "
3726 "load_user_data %p, frame_hierarchy %p, anim_controller %p.\n",
3728 load_user_data, frame_hierarchy, anim_controller);
3738 alloc_hier, load_user_data, frame_hierarchy, anim_controller);
3750 hr = filedata->lpVtbl->GetName(filedata,
NULL, &name_len);