Tomb Raider Forums  

Go Back   Tomb Raider Forums > Tomb Raider Level Editor and Modding > Tomb Raider Modding

Reply
 
Thread Tools
Old 21-02-24, 16:45   #81
MBJ_01
Member
 
Joined: Feb 2024
Posts: 3
Default

Quote:
Originally Posted by MuruCoder View Post
For textures check out this thread. Basically DDS has many different inner workings so it's not so straightforward getting them right.



You're welcome, happy modding



This depends on what you mean by rigging. You don't necessarily need to create an Armature (or skeleton) if you don't need to test how joints bend. What you need however is to assign vertices of the mesh to Vertex Groups in Blender. These vertex groups need to be in a specific order to work correctly. Even joint names don't matter. Just their vertex assignments and order. Lara outfits need 15 Blender vertex groups. If you import a model from another game, try to match this count and order their vertex groups like this and it might work well enough. For example a character's Right Hand vertex group should be moved to 11th place (or index 10 starting counting from 0).

Code:
0 Hip
1 Thigh left
2 Calf left
3 Foot left
4 Thigh right
5 Calf right
6 Foot right
7 Torso
8 Arm right
9 Elbow right
10 Hand right
11 Arm left
12 Elbow left
13 Hand left
14 Head
Alright, I'll keep that in mind. Thank you so much for the response! And also, thank you for making this script! It really opens up a door to a lot of modders for modding TR Remastered!
MBJ_01 is offline   Reply With Quote
Old 21-02-24, 17:17   #82
MaRaider
Member
 
MaRaider's Avatar
 
Joined: Feb 2024
Posts: 19
Default

Quote:
Originally Posted by MuruCoder View Post
trm_export.py
Code:
# v0.3

import bpy
import struct
import string
import math
import bmesh

def write_trm_data(context, filepath, use_trm_setting):
    print("EXPORTING...")
    f = open(filepath, 'wb')

    # TRM\x02 marker
    f.write(struct.pack(">I", 0x54524d02))

    # SELECT ACTIVE OBJECT & COPY
    trm = bpy.context.active_object
    trm_mesh = trm.data.copy()

    # TRIANGULATE COPY
    bm = bmesh.new()
    bm.from_mesh(trm_mesh)
    bmesh.ops.triangulate(bm, faces=bm.faces)
    bm.to_mesh(trm_mesh)
    bm.free()

    trm_mesh.calc_normals_split()

    # VERTEX PACKER
    def PackVertex(coordinate, normal, material, groups, uv):
        vx = -coordinate.x
        vy = -coordinate.z
        vz = -coordinate.y
        nr = NormalFLOAT2BYTE(-normal[0], -normal[2], -normal[1])
        nx = nr[0]
        ny = nr[1]
        nz = nr[2]
        mat = material + 1
        tu = int(uv[0] * 255)
        tv = 255 - int(uv[1] * 255)
        if len(groups) > 0:
            g1 = groups[0].group
            w1 = int(groups[0].weight * 255)
        else:
            g1 = 0
            w1 = 255
        if len(groups) > 1:
            g2 = groups[1].group
            w2 = int(groups[1].weight * 255)
        else:
            g2 = 0
            w2 = 0
        if len(groups) > 2:
            g3 = groups[2].group
            w3 = int(groups[2].weight * 255)
        else:
            g3 = 0
            w3 = 0
        return struct.pack("<fff12B", vx,vy,vz, nx,ny,nz, mat, g1,g2,g3, tu, w1,w2,w3, tv)

    # PREPARE INDICES & VERTICES DATA
    indices = []
    vertices = []

    uvs = trm_mesh.uv_layers.active
    v_order = [0, 2, 1]

    for p in trm_mesh.polygons:
        for i in v_order:
            loop = trm_mesh.loops[p.loop_indices[i]]
            groups = trm_mesh.vertices[loop.vertex_index].groups
            vertex = PackVertex(
                trm_mesh.vertices[loop.vertex_index].co,
                loop.normal,
                p.material_index,
                groups,
                uvs.data[p.loop_indices[i]].uv
            )
            if vertex in vertices:
                indices.append(vertices.index(vertex))
            else:
                indices.append(len(vertices))
                vertices.append(vertex)

    # GET ELEMENT COUNTS
    num_materials = len(trm_mesh.materials)
    print ("Materials: ", num_materials)
    num_indices = len(indices)
    print ("Indices: ", num_indices)
    num_vertices = len(vertices)
    print ("Vertices: ", num_vertices)

    # UNKNOWN DATA FILL
    f.write(struct.pack("<12I", 1, 0, 0, 0, 0, 0, 0, num_indices, num_indices, 0, num_indices, 0))

    # MATERIALS
    f.write(struct.pack("<I", num_materials))
    for n in range(num_materials):
        m = trm_mesh.materials[n]
        f.write(struct.pack("<H", int(m.name.split("_",1)[0])))

    # BYTE ALIGN
    while f.tell() % 4:
        f.write(b"\x00")

    # UNKNOWN and INDICE & VERTICE COUNTS
    f.write(struct.pack("<3I", 0, num_indices, num_vertices))

    # WRITE INDICES
    f.write(struct.pack("<%sH" % num_indices, *indices))

    # BYTE ALIGN
    while f.tell() % 4:
        f.write(b"\x00")

    # WRITE VERTICES
    for n in range(len(vertices)):
        f.write(vertices[n])

    f.close()
    print("DONE!")
    ShowAlert("Export Completed.", "COMPLETE!", "INFO")

    return {'FINISHED'}

def NormalFLOAT2BYTE(x, y, z):
    x = round(x * 126)
    y = round(y * 126)
    z = round(z * 126)
    return ( x + 127, y + 127, z + 127 )

def ShowAlert(message = '', title = '', icon = ''):
    def draw(self, context):
        self.layout.label(text = message)
    bpy.context.window_manager.popup_menu(draw, title = title, icon = icon)

from bpy_extras.io_utils import ExportHelper
from bpy.props import StringProperty, BoolProperty, EnumProperty
from bpy.types import Operator

class ExportTRMData(Operator, ExportHelper):
    """This appears in the tooltip of the operator and in the generated docs"""
    bl_idname = "export_tombraider.trm_data"
    bl_label = "Export TRM Data"

    filename_ext = ".TRM"

    filter_glob: StringProperty(
        default="*.TRM",
        options={'HIDDEN'},
        maxlen=255,
    )

    use_setting: BoolProperty(
        name="Example Boolean",
        description="Example Tooltip",
        default=True,
    )

    type: EnumProperty(
        name="Example Enum",
        description="Choose between two items",
        items=(
            ('OPT_A', "First Option", "Description one"),
            ('OPT_B', "Second Option", "Description two"),
        ),
        default='OPT_A',
    )

    def execute(self, context):
        return write_trm_data(context, self.filepath, self.use_setting)


def menu_func_export(self, context):
    self.layout.operator(ExportTRMData.bl_idname, text="TRM Export Operator")

def register():
    bpy.utils.register_class(ExportTRMData)
    bpy.types.TOPBAR_MT_file_export.append(menu_func_export)

def unregister():
    bpy.utils.unregister_class(ExportTRMData)
    bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)

if __name__ == "__main__":
    register()

    bpy.ops.export_tombraider.trm_data('INVOKE_DEFAULT')
I tried this new export script. I tried to remove Lara's backpack, and loaded the game Lara's body was gone. I wonder is stuff hardcoded or did something fail during the export?
MaRaider is offline   Reply With Quote
Old 21-02-24, 17:53   #83
MuruCoder
Member
 
MuruCoder's Avatar
 
Joined: Jan 2018
Posts: 1,432
Default

Quote:
Originally Posted by AmazingOomoo View Post
I just made a braid mod for Lara
I downloaded it too, looks good

Quote:
Originally Posted by MaRaider View Post
I tried to remove Lara's backpack, and loaded the game Lara's body was gone.
I tried the TR1 outfit, deleted backpack and belt, seems working. The textures have shadows that needs to be cleared though.

Click image for larger version

Name:	backpack_belt_deleted.jpg
Views:	139
Size:	44.8 KB
ID:	2915

If you are using a model you imported with earlier script, leave it. Import with the new import script. It's probably because normals are wrong.

Which outfit are you trying, there's some unknown data in Catsuit & Wetsuit. If those, the issue might be because of the unknown data.

Last edited by MuruCoder; 21-02-24 at 17:56.
MuruCoder is online now   Reply With Quote
Old 21-02-24, 18:00   #84
MaRaider
Member
 
MaRaider's Avatar
 
Joined: Feb 2024
Posts: 19
Default

I tried to modify the catsuit version of Lara. There were some odd geometry going on, I hope it's visible in this screencap. i(.)imgur(.)com/FCyg3fd.jpeg Remove the parenthesis.

Last edited by MaRaider; 21-02-24 at 18:18. Reason: Link get censored, not sure why.
MaRaider is offline   Reply With Quote
Old 21-02-24, 18:43   #85
TRDaz
Member
 
TRDaz's Avatar
 
Joined: May 2011
Posts: 10,466
Default

Quote:
Originally Posted by MuruCoder View Post
Yes, just import & export from scratch. Resize & rotate if you need but don't bother with rigging and all.
Still the same issue, unfortunately.
TRDaz is offline   Reply With Quote
Old 21-02-24, 18:44   #86
MuruCoder
Member
 
MuruCoder's Avatar
 
Joined: Jan 2018
Posts: 1,432
Default Materials/Textures and UVMaps

As explained in the format information, we know how many materials are used and their IDs. These IDs seem to correspond to the filenames in TEX folders. Blender can open DDS but these seem to be a newer edition of DDS so currently doesn't work. In later versions of Blender it might be possible. For now you'll have to resort to other tools for converting DDS into images you can work with or vice versa. Check out this thread or MaRaider' suggestions.

Click image for larger version

Name:	blender_materials.jpg
Views:	439
Size:	90.8 KB
ID:	2916

Anyway, my scripts keep track of these IDs as materials names. While the object is selected, click the red checkered looking sphere button to open Materials panel. In EDIT MODE you can Select/Deselect vertices assigned to a material with the buttons or Assign them to another. In the example image belt & boots are selected using the Select button. You should be able to add/remove materials safely. Just make sure you have at least 1 and all your vertices are assigned to a material.

Material names start with the number of the corresponding DDS file and then an underscore. You can change what comes after the underscore but Number + Underscore part must remain for the scripts to handle them. Materials are given a random color on import but don't bother with their properties like color or roughness. None of it gets imported or exported. They are basically placeholders to tell the script which IDs it should export into the TRM file. If you need to modify UV coordinates, find the DDS of the same number in TEX folder, convert with your method of choice into JPG then assign it to the Blender Material. Then work your magic in the UV Editor.

Name:  blender_uvmap.jpg
Views: 708
Size:  15.2 KB

In the Object Data panel under UV Maps tab there should be 1 UVMap. Normally you can have multiple uvmaps and their names can be changed, but my scripts need there to be only 1. When merging multiple meshes, make sure all of them has the same name for the uvmap. Otherwise you can end up with an object that has multiple uvmap layers and this can cause trouble while exporting.

Click image for larger version

Name:	blender_uvbounds.jpg
Views:	391
Size:	237.6 KB
ID:	3084

And last but not least, make sure your UV corrdinates are within the texture bounds. Values should be in 0.0-1.0 range inclusively. Even 1 vertex coordinate out of image area will halt the script.

Happy modding

Last edited by MuruCoder; 25-02-24 at 06:39.
MuruCoder is online now   Reply With Quote
Old 21-02-24, 19:02   #87
MaRaider
Member
 
MaRaider's Avatar
 
Joined: Feb 2024
Posts: 19
Default

Quote:
Originally Posted by MuruCoder View Post
I downloaded it too, looks good



I tried the TR1 outfit, deleted backpack and belt, seems working. The textures have shadows that needs to be cleared though.

Attachment 2915

If you are using a model you imported with earlier script, leave it. Import with the new import script. It's probably because normals are wrong.

Which outfit are you trying, there's some unknown data in Catsuit & Wetsuit. If those, the issue might be because of the unknown data.
Quote:
Originally Posted by MaRaider View Post
I tried to modify the catsuit version of Lara. There were some odd geometry going on, I hope it's visible in this screencap. i(.)imgur(.)com/FCyg3fd.jpeg Remove the parenthesis.
Okay my mistake, I diffed my script with yours, and combined them, so the scaling factors remained in the exported mesh. And that's why nothing showed up. So I added scaling up into the export script so it all works now as intended.

I think scaling down and scaling up should be they way to go, because objects aren't ridiculously large and they are easier to see immediately after importing.
MaRaider is offline   Reply With Quote
Old 21-02-24, 19:09   #88
MuruCoder
Member
 
MuruCoder's Avatar
 
Joined: Jan 2018
Posts: 1,432
Default

Quote:
Originally Posted by TRDaz View Post
Still the same issue, unfortunately.
Which model you downloaded, can you send me a link?

Quote:
Originally Posted by MaRaider View Post
I think scaling down and scaling up should be they way to go
I agree but I fear newcomers might have a lot sizing issues and confusion because of this. I also intend to post the Apply > All Transforms method to keep everyone on the same page.
MuruCoder is online now   Reply With Quote
Old 21-02-24, 19:19   #89
TRDaz
Member
 
TRDaz's Avatar
 
Joined: May 2011
Posts: 10,466
Default

Quote:
Originally Posted by MuruCoder View Post
Which model you downloaded, can you send me a link?
It's my own mod, I can private message you the model and textures.
TRDaz is offline   Reply With Quote
Old 21-02-24, 20:09   #90
MaRaider
Member
 
MaRaider's Avatar
 
Joined: Feb 2024
Posts: 19
Default

Quote:
Originally Posted by MuruCoder View Post
I agree but I fear newcomers might have a lot sizing issues and confusion because of this. I also intend to post the Apply > All Transforms method to keep everyone on the same page.
If you scale model down in the import... And scale model back up in the export, I don't see where's there going to be an issue at any point of the pipeline.

Maybe I'm just ignorant.. Like even if you create completely new model, it would be scaled up in the export, it should be the right size in the game and when you import it back. 🤔

Anyway I'll keep using and updating my custom script until some sort of sensible solution is found.
MaRaider is offline   Reply With Quote
Reply

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



All times are GMT. The time now is 21:42.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2025, vBulletin Solutions Inc.
Tomb Raider Forums is not owned or operated by CDE Entertainment Ltd.
Lara Croft and Tomb Raider are trademarks of CDE Entertainment Ltd.