Skip to content

Commit

Permalink
Merge pull request #134 from Simarilius-uk/main
Browse files Browse the repository at this point in the history
Sector Import: Fix indexs and a few tweaks to collisions
  • Loading branch information
Simarilius-uk authored Apr 18, 2024
2 parents bd5b202 + 8e3080a commit af44a74
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 30 deletions.
14 changes: 8 additions & 6 deletions i_scene_cp77_gltf/exporters/sectors_export.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Script to export CP2077 streaming sectors from Blender
# Just does changes to existing bits so far
# By Simarilius Jan 2023
# last updated 8-8-23
# latest version available at https://github.com/Simarilius-uk/CP2077_BlenderScripts
# use with the plugin from https://github.com/WolvenKit/Cyberpunk-Blender-add-on use 1.4RC or newer for wkit newer than Jul 4th 23
# last updated 17/4/24
# latest version in the plugin from https://github.com/WolvenKit/Cyberpunk-Blender-add-on
#
# __ __ ___ __ __ . . . . . . __ ___ __ ___ __ __ ___ __ . ___ . . . __
# / ` \ / |__) |__ |__) |__) | | |\ | |__/ /__` |__ / ` | / \ |__) |__ | \ | | | |\ | / _`
Expand All @@ -12,7 +11,7 @@
# Havent written a tutorial for this yet so thought I should add some instructions
# 1) Import the sector you want to edit using the Cyberpunk blender plugin (link above).
# 2) You can move the existing objects around and this will be exported
# 3) If you delete the mesh from a collector but leave the collector, the script will set the scale for that instance to -1 which stops it rendering in game
# 3) If you delete the mesh from a collector but leave the collector, the script will delete it with archivexl the file to do this is written to \source\resources
# 4) to add new stuff create a new collector with the sector name with _new on the end ie interior_1_1_0_1.streamingsector_new and then copy any objects you want into it.
# You need to copy the collector and the meshes for the nodes you want to copy, not just the meshes, the tags that make it work are on the collectors.
# 5) If its stuff already in the sector it will create nodeData nodes to instance it, if its from another imported sector it will copy the main node too
Expand Down Expand Up @@ -267,7 +266,7 @@ def find_wIDMN_col(NodeIndex,tl_inst_idx, sub_inst_idx,Sector_coll):

def find_decal(NodeIndex,Inst_idx,Sector_coll):
#print('Looking for NodeIndex ',NodeIndex,' Inst_idx ',Inst_idx, ' in ',Sector_coll)
col=[x for x in Sector_coll.objects if x['nodeIndex']==NodeIndex]
col=[x for x in Sector_coll.objects if 'nodeIndex' in x.keys() and x['nodeIndex']==NodeIndex]
if len(col)==0:
return None
elif len(col)==1:
Expand Down Expand Up @@ -895,7 +894,10 @@ def exportSectors( filename):
print('inserting at ',idx)
wtbbuffer['Transforms'].insert(idx,trans)
print('After = ',len(wtbbuffer['Transforms']))


# need to process the sector_coll sectors and look for deleted collision bodies



# Export the modified json
sectpathout=os.path.join(projpath,os.path.splitext(os.path.basename(filename))[0]+'.streamingsector.json')
Expand Down
74 changes: 50 additions & 24 deletions i_scene_cp77_gltf/importers/sector_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import traceback
from pprint import pprint
from ..main.setup import MaterialBuilder
from ..main.collisions import set_collider_props
from operator import add
import bmesh
VERBOSE=True
Expand Down Expand Up @@ -222,7 +223,8 @@ def importSectors( filepath='', want_collisions=False, am_modding=False, with_ma
print(jsonpath)
meshes=[]
C = bpy.context

# Use object wireframe colors not theme - doesnt work need to find hte viewport as the context doesnt return that for this call
# bpy.context.space_data.shading.wireframe_color_type = 'OBJECT'
for filepath in jsonpath:
if filepath==os.path.join(path,os.path.basename(project)+'.streamingsector.json'):
continue
Expand Down Expand Up @@ -340,6 +342,9 @@ def importSectors( filepath='', want_collisions=False, am_modding=False, with_ma
j=json.load(f)

t=j['Data']['RootChunk']['nodeData']['Data']
# add nodeDataIndex props to all the nodes in t
for index, obj in enumerate(t):
obj['nodeDataIndex']=index

numExpectedNodes = len(t)
sectorName=os.path.basename(filepath)[:-5]
Expand Down Expand Up @@ -408,7 +413,7 @@ def importSectors( filepath='', want_collisions=False, am_modding=False, with_ma
Sector_coll.children.link(new)
new['nodeType']=type
new['nodeIndex']=i
new['nodeDataIndex']=next((index for index, obj in enumerate(t) if obj['NodeIndex'] == i), None)
new['nodeDataIndex']=inst['nodeDataIndex']
new['instance_idx']=idx
new['debugName']=e['Data']['debugName']
new['sectorName']=sectorName
Expand Down Expand Up @@ -499,7 +504,7 @@ def importSectors( filepath='', want_collisions=False, am_modding=False, with_ma
Sector_coll.children.link(new)
new['nodeType']=type
new['nodeIndex']=i
new['nodeDataIndex']=next((index for index, obj in enumerate(t) if obj['NodeIndex'] == i), None)
new['nodeDataIndex']=inst['nodeDataIndex']
new['mesh']=meshname
new['debugName']=e['Data']['debugName']
new['sectorName']=sectorName
Expand Down Expand Up @@ -555,7 +560,7 @@ def importSectors( filepath='', want_collisions=False, am_modding=False, with_ma
Sector_coll.children.link(new)
new['nodeType']=type
new['nodeIndex']=i
new['nodeDataIndex']=next((index for index, obj in enumerate(t) if obj['NodeIndex'] == i), None)
new['nodeDataIndex']=inst['nodeDataIndex']
new['instance_idx']=idx
new['mesh']=meshname
new['debugName']=e['Data']['debugName']
Expand Down Expand Up @@ -617,21 +622,27 @@ def importSectors( filepath='', want_collisions=False, am_modding=False, with_ma
o.scale = get_scale(inst)
#o.empty_display_size = 0.002
#o.empty_display_type = 'IMAGE'
mipath = o['decal']
jsonpath = os.path.join(path,mipath)+".json"
#print(jsonpath)
try:
with open(jsonpath,'r') as jsonpath:
obj=json.load(jsonpath)
index = 0
obj["Data"]["RootChunk"]['alpha'] = e['Data']['alpha']
#FIXME: image_format
builder = MaterialBuilder(obj,path,'png',path)
bpymat = builder.create(index)
o.data.materials.append(bpymat)
except FileNotFoundError:
name = os.path.basename(jsonpath)
print(f'File not found {name} ({jsonpath}), you need to export .mi files')
if with_materials:
mipath = o['decal']
jsonpath = os.path.join(path,mipath)+".json"
#print(jsonpath)
try:
with open(jsonpath,'r') as jsonpath:
obj=json.load(jsonpath)
index = 0
obj["Data"]["RootChunk"]['alpha'] = e['Data']['alpha']
#FIXME: image_format
builder = MaterialBuilder(obj,path,'png',path)
bpymat = builder.create(index)
o.data.materials.append(bpymat)
except FileNotFoundError:
name = os.path.basename(jsonpath)
print(f'File not found {name} ({jsonpath}), you need to export .mi files')
else:
o.display_type = 'WIRE'
o.color = (1.0, 0.905, .062, 1)
o.show_wire = True
o.display.show_shadows = False

case 'XworldStaticOccluderMeshNode':
#print('worldStaticOccluderMeshNode',i)
Expand Down Expand Up @@ -694,7 +705,7 @@ def importSectors( filepath='', want_collisions=False, am_modding=False, with_ma
Sector_coll.children.link(new)
new['nodeType']=type
new['nodeIndex']=i
new['nodeDataIndex']=next((index for index, obj in enumerate(t) if obj['NodeIndex'] == i), None)
new['nodeDataIndex']=inst['nodeDataIndex']
new['mesh']=meshname
new['debugName']=e['Data']['debugName']
new['sectorName']=sectorName
Expand Down Expand Up @@ -751,7 +762,7 @@ def importSectors( filepath='', want_collisions=False, am_modding=False, with_ma
Sector_coll.children.link(new)
new['nodeType']=type
new['nodeIndex']=i
new['nodeDataIndex']=next((index for index, obj in enumerate(t) if obj['NodeIndex'] == i), None)
new['nodeDataIndex']=inst['nodeDataIndex']
new['instance_idx']=idx
new['mesh']=meshname
new['debugName']=e['Data']['debugName']
Expand Down Expand Up @@ -811,7 +822,7 @@ def importSectors( filepath='', want_collisions=False, am_modding=False, with_ma
Sector_coll.children.link(new)
new['nodeType']=type
new['nodeIndex']=i
new['nodeDataIndex']=next((index for index, obj in enumerate(t) if obj['NodeIndex'] == i), None)
new['nodeDataIndex']=inst['nodeDataIndex']
new['tl_instance_idx']=instidx
new['sub_instance_idx']=idx
new['mesh']=meshname
Expand Down Expand Up @@ -917,6 +928,7 @@ def importSectors( filepath='', want_collisions=False, am_modding=False, with_ma
else:
sector_Collisions_coll=bpy.data.collections.new(sector_Collisions)
coll_scene.children.link(sector_Collisions_coll)
inst = [x for x in t if x['NodeIndex'] == i][0]
Actors=e['Data']['compiledData']['Data']['Actors']
for idx,act in enumerate(Actors):
#print(len(act['Shapes']))
Expand All @@ -937,12 +949,19 @@ def importSectors( filepath='', want_collisions=False, am_modding=False, with_ma
loc=(spos[0]+x,spos[1]+y,spos[2]+z)
bpy.ops.mesh.primitive_cube_add(size=1/scale_factor, scale=(ssize['X'],ssize['Y'],ssize['Z']),location=loc)
cube=C.selected_objects[0]
cube.name='NodeDataIndex_'+str(inst['nodeDataIndex'])+'_Actor_'+str(idx)+'_Shape_'+str(s)
par_coll=cube.users_collection[0]
par_coll.objects.unlink(cube)
sector_Collisions_coll.objects.link(cube)
cube['nodeIndex']=i
cube['nodeDataIndex']=inst['nodeDataIndex']
cube['ShapeType']=shape['ShapeType']
cube['ShapeNo']=s
cube['ActorIdx']=idx
cube['sectorName']=sectorName
cube.rotation_mode='QUATERNION'
cube.rotation_quaternion=rot
set_collider_props(cube, shape['ShapeType'], shape['Materials'][0]['$value'], 'WORLD')

elif shape['ShapeType']=='Capsule':
#print('Capsule Collision Node')
Expand All @@ -955,14 +974,21 @@ def importSectors( filepath='', want_collisions=False, am_modding=False, with_ma
loc=(spos[0]+x,spos[1]+y,spos[2]+z)
bpy.ops.mesh.primitive_cylinder_add(radius=5/scale_factor, depth=1/scale_factor, scale=(ssize['X'],ssize['Y'],ssize['Z']),location=loc)
capsule=C.selected_objects[0]
capsule.name='NodeDataIndex_'+str(inst['nodeDataIndex'])+'_Actor_'+str(idx)+'_Shape_'+str(s)
par_coll=capsule.users_collection[0]
par_coll.objects.unlink(capsule)
sector_Collisions_coll.objects.link(capsule)
capsule['nodeIndex']=i
capsule['nodeDataIndex']=inst['nodeDataIndex']
capsule['ShapeType']=shape['ShapeType']
capsule['ShapeNo']=s
capsule['ActorIdx']=idx
capsule['sectorName']=sectorName
capsule['sectorName']=sectorName
capsule.rotation_mode='QUATERNION'
capsule.rotation_quaternion=rot
set_collider_props(cube, shape['ShapeType'], shape['Materials'][0]['$value'], 'WORLD')
else:
print(f"skipping unsuppored shape {shape['ShapeType']}")
print(f"skipping unsupported shape {shape['ShapeType']}")


case _:
Expand Down

0 comments on commit af44a74

Please sign in to comment.