Jump to content

Need help regarding a c++ script which inject data into binary file


Recommended Posts

Posted (edited)

I need some help regarding the c++ script i wrote it reads normal data as floats from obj file then convert it into byte and inject it into the binary game file but some how the normals data mess will vertices data and in game the vertices explodes without normal injection the mesh works fine in game. Also that normal data is within the vertices section. I have provided pic of the AXE mesh reaper u can see normal starting offset in file as well as face count vertices every info in the image also i have provided the model file as well and my c++ code which only inject normals from obj into the binary file you can check the script and see where my mistake and correct it i will be really obliged, thanks.

Screenshot 2024-05-29 061038.png

normal injector.rar

Wei_Head.perm.zip

Edited by Silence Exterminator
Link to comment
Share on other sites

Posted (edited)

Seems you're reading 3 floats at 0x8050. (But the next vertex block starts at 0x8058.)

There's 2 DWords at 0x8050, MSB is 0xFF each. 2x24= 48 bits. So 2 bytes for each normal's component?

(Stated this already at 24th of May, see your "Wei's head" post.) edit: yeah, but seems, it's 1 byte per normals component.

edit3: from this code snippet:

for (float component : normal) {
        char byte = static_cast<char>((component + 1.0f) * 127.0f); // Convert float to Byte range
        file.write(&byte, sizeof(char));
    }

it's not clear, what normals: or component: normal is...

Edited by shak-otay
Link to comment
Share on other sites

14 hours ago, shak-otay said:

Seems you're reading 3 floats at 0x8050. (But the next vertex block starts at 0x8058.)

There's 2 DWords at 0x8050, MSB is 0xFF each. 2x24= 48 bits. So 2 bytes for each normal's component?

(Stated this already at 24th of May, see your "Wei's head" post.)

edit2: ah, see, Bigchillghost gave the code already:

for (float component : normal) {
        char byte = static_cast<char>((component + 1.0f) * 127.0f); // Convert float to Byte range
        file.write(&byte, sizeof(char));
    }

but it's not clear, what normals:: normal is...

hi how are u, so can u explain more about the normals in detail: "There's 2 DWords at 0x8050, MSB is 0xFF each. 2x24= 48 bits. So 2 bytes for each normal's component?" also what i think the normals are that in binary file there is 12 bytes vertices data then 4 bytes zero data probably non used vertice color then normal are 3bytes then 5 byte tangent as u can see in the image provided sorry for the mistake as for normals i highlighted 4 bytes in green thats wrong normal is 3 byte then tangent is 5 bytes.

Screenshot 2024-06-01 073200.png

Link to comment
Share on other sites

Posted (edited)
On 6/1/2024 at 11:32 PM, Silence Exterminator said:

hi how are u, so can u explain more about the normals in detail: "There's 2 DWords at 0x8050, MSB is 0xFF each. 2x24= 48 bits. So 2 bytes for each normal's component?" 

Hi- I'm fine, hope, you're, too. 2 bytes for normal x,y,z each out of 48 bits (in sum) means: aabbccFF ddeeffFF -> x= aabb; y= ccdd; z= eeff; (as 16 bit ints or signed shorts).

you'll get this by masking and shifting aabbccFF and ddeeffFF. And concatenating cc and dd, of course. That's how I'd do it. Shift right by 16 bits is the same as dividing by 65536, just in case

edit: forget that. Bigchillghost already told you that it's byte components for normals xn,yn,zn, i.e. 8, not 16 bits.

(To check your result: square (x) + square (y) + square (z)=1, for normals.)

Edited by shak-otay
  • Like 1
Link to comment
Share on other sites

Posted (edited)
15 hours ago, shak-otay said:

Hi- I'm fine, hope, you're, too. 2 bytes for normal x,y,z each out of 48 bits (in sum) means: aabbccFF ddeeffFF -> x= aabb; y= ccdd; z= eeff; (as 16 bit ints or signed shorts).

you'll get this by masking and shifting aabbccFF and ddeeffFF. And concatenating cc and dd, of course. That's how I'd do it. Shift right by 16 bits is the same as dividing by 65536, just in case

(To check your result: square (x) + square (y) + square (z)=1, for normals.)

 

(btw, seems Bigchillghost handles 4 bytes as floats; "component" is unclear for me.)

so the data as shown in my image is not correct? if yes can u please identify me the bytes for normal on the same image just highlight them so i can better understand, thanks

Screenshot 2024-06-01 073200.png

Edited by Silence Exterminator
Link to comment
Share on other sites

Posted (edited)

Hmm, normals components as bytes? Now Bigchillghost's code makes sense to me.😄

I'd suggest you try out his code and make the xn,yn,zn "square sum==1?" check then.

(If that works all is fine. If not use 2 bytes for each normal component as I've shown.)

Edited by shak-otay
Link to comment
Share on other sites

11 minutes ago, shak-otay said:

Hmm, normals components as bytes? Now Bigchillghost's code makes sense to me.😄

I'd suggest you try out his code and make the xn,yn,zn "square sum==1?" check then.

(If that works all is fine. If not use 2 bytes for each normal component as I've shown.)

bro i get that but did u saw my image i provided can u please highlight the bytes u think is normal that would help me alot to understand to what are u reffering to

Link to comment
Share on other sites

Posted (edited)

Sorry; I can't highlight anything as long as we don't know whether it's 8 bit or 16 bit normal's components.:classic_sad:

btw: no matter which version I choose, square sum of components is not 1.

Why not use AMR to display the normals as bytes? They should show up as a sphere.

What does AMR display in preview with "normals" selected?

 

Edited by shak-otay
Link to comment
Share on other sites

Posted (edited)

 Thought I have made it clear already:

On 5/31/2024 at 9:48 PM, Bigchillghost said:

The "blue" (bytes after the 3 position floats) are the normal plus the tangent, the leading zero bytes might be an unused vertex color channel.

And I've already posted the code for decoding:

On 5/31/2024 at 9:48 PM, Bigchillghost said:
uint8_t aByte = 0;
file.read((char *)&aByte, 1);
float toFloat = (aByte / 255.0) * 2.0 - 1.0;

So as the solution to your problem:

On 5/31/2024 at 6:24 AM, Silence Exterminator said:

but some how the normals data mess will vertices data

On 5/31/2024 at 9:48 PM, Bigchillghost said:
for (const auto& normal : normals) {
    ...
    for (float component : normal) {
        ...
    }
    // #### file.seekp(0x15, ios::cur) is required here!!! 0x15 == 24 - 3 bytes for the written normal
    ...
}

But it seems you‘re not paying attention and didn't answer any of my questions.

 

On 6/1/2024 at 2:37 PM, shak-otay said:

edit2: ah, see, Bigchillghost gave the code already

These are not my code, I just quoted them from his .cpp source from the other thread. And don't over think the FF byte. It's not used but just for byte alignment to 4.

Edited by Bigchillghost
  • Thanks 1
Link to comment
Share on other sites

10 hours ago, shak-otay said:

Very funny: finally I learned how it comes to 8 bit normals' components: it's when they are calculate from RGB values of a normal map.

Not a specialist in graphics but I don't think that's how they're related. The 8-bit encoding for vertex normals should be a simple quantization from the floating-point values. As for the RGB values of a normal map, though they seem similar in encoding, yet they should be totally different techniques.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...