Matteo Bruni : d3dx9/mesh: Split skin header and weights parse functions.

Alexandre Julliard julliard at winehq.org
Tue May 17 15:37:22 CDT 2022


Module: wine
Branch: master
Commit: b6b6561aa3044568c0114ee132dafb53270e42d5
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=b6b6561aa3044568c0114ee132dafb53270e42d5

Author: Matteo Bruni <mbruni at codeweavers.com>
Date:   Tue Apr 26 06:10:09 2022 +0200

d3dx9/mesh: Split skin header and weights parse functions.

They don't really share any code in common.

Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/d3dx9_36/mesh.c | 92 ++++++++++++++++++++++++++++++----------------------
 1 file changed, 53 insertions(+), 39 deletions(-)

diff --git a/dlls/d3dx9_36/mesh.c b/dlls/d3dx9_36/mesh.c
index 9871f62dfc4..7252e2f8fdd 100644
--- a/dlls/d3dx9_36/mesh.c
+++ b/dlls/d3dx9_36/mesh.c
@@ -3117,55 +3117,69 @@ end:
     return hr;
 }
 
-static HRESULT parse_skin_mesh_info(ID3DXFileData *filedata, struct mesh_data *mesh_data, DWORD index)
+static HRESULT parse_skin_mesh_header(ID3DXFileData *filedata, struct mesh_data *mesh_data)
 {
-    HRESULT hr;
-    SIZE_T data_size;
     const BYTE *data;
+    SIZE_T data_size;
+    HRESULT hr;
 
-    TRACE("(%p, %p, %u)\n", filedata, mesh_data, index);
+    TRACE("filedata %p, mesh_data %p.\n", filedata, mesh_data);
 
-    hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void**)&data);
-    if (FAILED(hr)) return hr;
+    if (FAILED(hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void **)&data)))
+        return hr;
 
-    hr = E_FAIL;
+    if (data_size < sizeof(WORD) * 3)
+    {
+        WARN("Truncated data (%Id bytes).\n", data_size);
+        filedata->lpVtbl->Unlock(filedata);
+        return E_FAIL;
+    }
+    /* Skip nMaxSkinWeightsPerVertex and nMaxSkinWeightsPerFace */
+    data += 2 * sizeof(WORD);
+    mesh_data->bone_count = *(WORD *)data;
+    hr = D3DXCreateSkinInfoFVF(mesh_data->num_vertices, mesh_data->fvf, mesh_data->bone_count,
+            &mesh_data->skin_info);
 
-    if (!mesh_data->skin_info) {
-        if (data_size < sizeof(WORD) * 3) {
-            WARN("truncated data (%ld bytes)\n", data_size);
-            goto end;
-        }
-        /* Skip nMaxSkinWeightsPerVertex and nMaxSkinWeightsPerFace */
-        data += 2 * sizeof(WORD);
-        mesh_data->bone_count = *(WORD*)data;
-        hr = D3DXCreateSkinInfoFVF(mesh_data->num_vertices, mesh_data->fvf, mesh_data->bone_count, &mesh_data->skin_info);
-    } else {
-        const char *name;
-        DWORD nb_influences;
+    return hr;
+}
 
-        /* FIXME: String must be retrieved directly instead of through a pointer once ID3DXFILE is fixed */
-        name = *(const char**)data;
-        data += sizeof(char*);
+static HRESULT parse_skin_weights_info(ID3DXFileData *filedata, struct mesh_data *mesh_data, unsigned int index)
+{
+    unsigned int influence_count;
+    const char *name;
+    const BYTE *data;
+    SIZE_T data_size;
+    HRESULT hr;
 
-        nb_influences = *(DWORD*)data;
-        data += sizeof(DWORD);
+    TRACE("filedata %p, mesh_data %p, index %u.\n", filedata, mesh_data, index);
 
-        if (data_size < (sizeof(char*) + sizeof(DWORD) + nb_influences * (sizeof(DWORD) + sizeof(FLOAT)) + 16 * sizeof(FLOAT))) {
-            WARN("truncated data (%ld bytes)\n", data_size);
-            goto end;
-        }
+    if (FAILED(hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void **)&data)))
+        return hr;
+
+    /* FIXME: String will have to be retrieved directly instead of through a
+     * pointer once our ID3DXFileData implementation is fixed. */
+    name = *(const char **)data;
+    data += sizeof(char *);
+
+    influence_count = *(uint32_t *)data;
+    data += sizeof(uint32_t);
 
-        hr = mesh_data->skin_info->lpVtbl->SetBoneName(mesh_data->skin_info, index, name);
-        if (SUCCEEDED(hr))
-            hr = mesh_data->skin_info->lpVtbl->SetBoneInfluence(mesh_data->skin_info, index, nb_influences,
-                     (const DWORD*)data, (const FLOAT*)(data + nb_influences * sizeof(DWORD)));
-        if (SUCCEEDED(hr))
-            hr = mesh_data->skin_info->lpVtbl->SetBoneOffsetMatrix(mesh_data->skin_info, index,
-                     (const D3DMATRIX*)(data + nb_influences * (sizeof(DWORD) + sizeof(FLOAT))));
+    if (data_size < (sizeof(char *) + sizeof(uint32_t) + influence_count * (sizeof(uint32_t) + sizeof(float))
+            + 16 * sizeof(float)))
+    {
+        WARN("Truncated data (%Id bytes).\n", data_size);
+        filedata->lpVtbl->Unlock(filedata);
+        return E_FAIL;
     }
 
-end:
-    filedata->lpVtbl->Unlock(filedata);
+    hr = mesh_data->skin_info->lpVtbl->SetBoneName(mesh_data->skin_info, index, name);
+    if (SUCCEEDED(hr))
+        hr = mesh_data->skin_info->lpVtbl->SetBoneInfluence(mesh_data->skin_info, index, influence_count,
+                (const DWORD *)data, (const float *)(data + influence_count * sizeof(uint32_t)));
+    if (SUCCEEDED(hr))
+        hr = mesh_data->skin_info->lpVtbl->SetBoneOffsetMatrix(mesh_data->skin_info, index,
+                (const D3DMATRIX *)(data + influence_count * (sizeof(uint32_t) + sizeof(float))));
+
     return hr;
 }
 
@@ -3317,7 +3331,7 @@ static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data,
                     hr = E_FAIL;
                     goto end;
                 }
-                hr = parse_skin_mesh_info(child, mesh_data, 0);
+                hr = parse_skin_mesh_header(child, mesh_data);
                 if (FAILED(hr))
                     goto end;
             } else if (IsEqualGUID(&type, &DXFILEOBJ_SkinWeights)) {
@@ -3326,7 +3340,7 @@ static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data,
                     hr = E_FAIL;
                     goto end;
                 }
-                hr = parse_skin_mesh_info(child, mesh_data, skin_weights_info_count);
+                hr = parse_skin_weights_info(child, mesh_data, skin_weights_info_count);
                 if (FAILED(hr))
                     goto end;
                 skin_weights_info_count++;




More information about the wine-cvs mailing list