Markemp / Cryengine-Converter

A c# program to convert Crytek files to Collada (XML) format
https://www.heffaypresents.com/GitHub/
GNU General Public License v2.0
208 stars 53 forks source link

Star Citizen conversion of .skin file fails #146

Closed mortik closed 1 year ago

mortik commented 1 year ago

When i try to convert a skin file of Star Citizen Armor it returns the following error:

PS D:\scdata> .\cgf-converter.exe "D:\scdata-3.17.4\Data\Objects\Characters\Human\male_v7\armor\nvy\pilot_flightsuit\m_nvy_pilot_light_helmet_01.skin" -noconflict -objectdir "D:\scdata-3.17.4\Data"
Prevent conflicts for mtl files enabled
Data directory set to D:\scdata-3.17.4\Data
Processing input file(s):
D:\scdata-3.17.4\Data\Objects\Characters\Human\male_v7\armor\nvy\pilot_flightsuit\m_nvy_pilot_light_helmet_01.skin

********************************************************************************
There was an error rendering D:\scdata-3.17.4\Data\Objects\Characters\Human\male_v7\armor\nvy\pilot_flightsuit\m_nvy_pilot_light_helmet_01.skin

An item with the same key has already been added. Key: 6

   at System.Collections.Generic.Dictionary`2.TryInsert(TKey , TValue , InsertionBehavior )
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
   at CgfConverter.CryEngineCore.Chunks.ChunkIvoSkin_900.Read(BinaryReader b)
   at CgfConverter.CryEngineCore.Model.ReadChunks(BinaryReader reader)
   at CgfConverter.CryEngineCore.Model.Load(String fileName)
   at CgfConverter.CryEngine.ProcessCryengineFiles()
   at CgfConverterConsole.Program.Main(String[] args)
********************************************************************************

PS D:\scdata>

And another error on an other .skin file

PS D:\scdata> .\cgf-converter.exe "D:\scdata-3.17.4-live\Data\Objects\Characters\Human\male_v7\armor\outlaw\m_outlaw_legacy_heavy_armor_helmet_02.skin" -objectdir "D:\scdata-3.17.4-live\Data"
Data directory set to D:\scdata-3.17.4-live\Data
Processing input file(s):
D:\scdata-3.17.4-live\Data\Objects\Characters\Human\male_v7\armor\outlaw\m_outlaw_legacy_heavy_armor_helmet_02.skin
Unable to find material file for outlaw_legacy_heavy_armor_helmet_02_01_01.mtl
Unable to find material file for outlaw_legacy_heavy_armor_helmet_02_01_01.mtl

********************************************************************************
There was an error rendering D:\scdata-3.17.4-live\Data\Objects\Characters\Human\male_v7\armor\outlaw\m_outlaw_legacy_heavy_armor_helmet_02.skin

Object reference not set to an instance of an object.

   at CgfConverter.Collada.CreateMaterialsFromNodeChunk(ChunkNode nodeChunk)
   at CgfConverter.Collada.WriteGeometries(Model model)
   at CgfConverter.Collada.WriteLibrary_Geometries()
   at CgfConverter.Collada.GenerateDaeObject()
   at CgfConverter.Collada.Render(String outputDir, Boolean preservePath)
   at CgfConverterConsole.Program.Main(String[] args)
********************************************************************************

PS D:\scdata>

cgf-converter version: 1.4.0

giniedp commented 1 year ago

The second error is actually failing in this line https://github.com/Markemp/Cryengine-Converter/blob/9982d5e205bd40b51d557ccb0d0c1e713427d217/CgfConverter/Renderers/Collada/COLLADA.cs#L765

DaeObject.Library_Materials is not null but DaeObject.Library_Materials.Material is and the actual is null check fails. Anyone knows how this can be or how it can be fixed?

Kjasi commented 1 year ago

After looking at it, best I can figure out is that it could be that the Material is NOT null, but it's not a correctly defined Array.Empty<Grendgine_Collada_Material>(). A secondary check for that (after line 766) would be the correct fix, if that is the issue. Keep in mind, we'd mostly need to check to see if DaeObject.Library_Materials.Material is an array of Grendgine_Collada_Material type, in case it already exists. We don't want to overwrite any values already inside there...

giniedp commented 1 year ago

tried it with

if (!(DaeObject.Library_Materials.Material?.GetType()?.IsArray ?? false))

but it fails too. When i remove the if condition, the stack trace points to the previous line

List<Grendgine_Collada_Effect> colladaEffects = new();
giniedp commented 1 year ago

turns out the SubMaterials are null in the next line with the foreach loop

foreach (var mat in nodeChunk.Materials.SubMaterials)

adding a null guard makes this function go through without errors. Now i need to check why SubMaterials are actually null, since the given mtl file does have SubMaterials.

Markemp commented 1 year ago

Taking a look at this now. Created a branch issues-146-materials-nre for this issue.

Markemp commented 1 year ago

I must be looking at an older version of this file. I think the last one I have is from 3.12 or so. I'm running into an issue with duplicate Normals datastream.

Kjasi commented 1 year ago

Well, the first file the error is about is from a version of the game that's under NDA at the moment (that might change this coming week) but the second one is the current version of the game, 3.17.4.

mortik commented 1 year ago

Well, the first file the error is about is from a version of the game that's under NDA at the moment (that might change this coming week) but the second one is the current version of the game, 3.17.4.

You will see the same error in the 3.17.4 Gamefiles for both mentioned files, so i highly doubt that the issue is related to changes in 3.18

I updated the description to reflect that the issue is present in the latest LIVE release 3.17.4

Markemp commented 1 year ago

Yup, I was looking at the wrong file. I'll add integration tests for both of these and get a fix going.

I hate Cryengine material handling. 😡

Markemp commented 1 year ago

image

Pilot helmet. Going to work on the other file now.

Markemp commented 1 year ago

The outlaw helmet has the wrong file name for the armor. In the data files, it's listed as outlaw_legacy_heavy_armor_helmet_02_01_01, but the actual file is probably m_outlaw_legacy_heavy_armor_helmet_02_01_01.mtl. I'm not really sure I can fix this with the code. It might make sense to copy the material file and rename it without the leading m_.

Markemp commented 1 year ago

Figured out the Ivo file rotations. 💪 image