diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4f48ad7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +# Godot-specific ignores +.import/ +export.cfg +export_presets.cfg + +# Imported translations (automatically generated from CSV files) +*.translation + +# Mono-specific ignores +.mono/ +data_*/ diff --git a/autoload/ChunkEditor.gd b/autoload/ChunkEditor.gd new file mode 100644 index 0000000..81e39f4 --- /dev/null +++ b/autoload/ChunkEditor.gd @@ -0,0 +1,63 @@ +extends Node + +var cam +var gizmo +var menu_cityobj_selected + +var selected_cityobj: Spatial + +func _ready(): + get_tree().connect("files_dropped", self, "_on_files_dropped") + +func _unhandled_input(event): + if event is InputEventMouseButton: + if event.button_index == BUTTON_LEFT and event.is_pressed(): + _unselect_cityobj() + +func _on_files_dropped(files, _screen): + if len(files) != 1: + print("One file at a time!") + return + var filepath = files[0] + ChunkHandler.LoadChunk(filepath) + +func _select_cityobj(obj: Spatial): + if menu_cityobj_selected: + _unselect_cityobj() + selected_cityobj = obj + selected_cityobj._set_highlight(true) + gizmo.translation = selected_cityobj.translation + + menu_cityobj_selected._select(obj) + menu_cityobj_selected.show() + +func _unselect_cityobj(): + if menu_cityobj_selected: + if selected_cityobj: + selected_cityobj._set_highlight(false) + selected_cityobj = null + menu_cityobj_selected.hide() + +func _save(): + ChunkHandler.SaveChunk() + +func _clear(): + ChunkHandler.ClearChunk() + get_tree().reload_current_scene() + +func _process(_delta): + if gizmo: + if selected_cityobj: + gizmo.show() + gizmo.scale = Vector3.ONE * cam.get_node("pivot").get_node("cam").transform.origin.z * .2 + + gizmo.translation = selected_cityobj.translation + + else: + gizmo.hide() + + # Input + # Focus on selected + if Input.is_key_pressed(KEY_F): + if selected_cityobj: + cam.translation = selected_cityobj.translation diff --git a/autoload/ChunkHandler.cs b/autoload/ChunkHandler.cs new file mode 100644 index 0000000..0e3719e --- /dev/null +++ b/autoload/ChunkHandler.cs @@ -0,0 +1,132 @@ +using Godot; +using System; +using System.IO; + +public class ChunkHandler : Node +{ + ChunkLoader chunkLoader; + ChunkUnloader chunkUnloader; + + CPUChunk loadedChunk; + string loadedChunkPath; + + public override void _Ready() + { + chunkLoader = GetNode("/root/ChunkLoader") as ChunkLoader; + chunkUnloader = new ChunkUnloader(); + } + + public void ClearChunk() + { + loadedChunk = null; + } + + public void LoadChunk(string input_filepath) + { + string cpu_chunk_filepath = ""; + string gpu_chunk_filepath = ""; + // string peg_filepath; + + GD.Print(input_filepath); + + // File Exist + if (!System.IO.File.Exists(input_filepath)) + { + GD.Print("Error: Input File Doesn't Exist! " + input_filepath); + return; + } + + // File Extension + if (System.IO.Path.GetExtension(input_filepath) == ".chunk_pc") + { + cpu_chunk_filepath = input_filepath; + gpu_chunk_filepath = System.IO.Path.ChangeExtension(input_filepath, ".g_chunk_pc"); + } + else if (System.IO.Path.GetExtension(input_filepath) == ".g_chunk_pc") + { + cpu_chunk_filepath = System.IO.Path.ChangeExtension(input_filepath, ".chunk_pc"); + gpu_chunk_filepath = input_filepath; + } + else if (System.IO.Path.GetExtension(input_filepath) == ".g_peg_pc") + { + cpu_chunk_filepath = System.IO.Path.ChangeExtension(input_filepath, ".chunk_pc"); + gpu_chunk_filepath = System.IO.Path.ChangeExtension(input_filepath, ".g_chunk_pc"); + } + else + { + GD.Print("Error: Unknown extension!"); + return; + } + + // Chunkfile Exist + if (!System.IO.File.Exists(cpu_chunk_filepath)) + { + GD.Print("Error: " + cpu_chunk_filepath + " doesn't exist!"); + return; + } + if (!System.IO.File.Exists(gpu_chunk_filepath)) + { + GD.Print("Error: " + gpu_chunk_filepath + " doesn't exist!"); + return; + } + + loadedChunk = chunkLoader.LoadChunk(cpu_chunk_filepath); + loadedChunkPath = cpu_chunk_filepath; + if (loadedChunk != null) + { + chunkLoader.LoadGPUChunk(loadedChunk, gpu_chunk_filepath); + ImportChunkToScene(loadedChunk); + } + else + { + GD.PushWarning("ChunkLoader returned null."); + } + } + + public void ImportChunkToScene(CPUChunk chunk) + { + Node world = GetNode("/root/main/chunk/cityobjects"); + for (int i = 0; i < chunk.cityObjectCount; i++) + { + CityObject cityObject = chunk.cityObjects[i]; + uint partId = cityObject.cityObjectPart; + CityObjectPart temp = chunk.cityObjectParts[partId]; + + Spatial cityObjectNode = new Spatial(); + cityObjectNode.SetScript(ResourceLoader.Load("res://scenes/editor/scripts/cityobject.gd")); + cityObjectNode.Translation = temp.pos; + cityObjectNode.Name = cityObject.name; + cityObjectNode.Set("rendermodel_id", temp.model); + cityObjectNode.Set("cityobjpart_id", partId); + + world.AddChild(cityObjectNode); + } + Spatial camera = (Spatial)GetNode("/root/main/editor/cameraman"); + camera.Translation = chunk.cityObjectParts[0].pos; + } + + public void SaveChunk() + { + // Get cityobject data from nodes + Node cityObjContainer = GetNode("/root/main/chunk/cityobjects"); + for (int i = 0; i < cityObjContainer.GetChildCount(); i++) + { + Spatial cityObjNode = cityObjContainer.GetChild(i) as Spatial; + uint model = (uint)(int)cityObjNode.Get("rendermodel_id"); + Vector3 pos = cityObjNode.Translation; + + uint partid = loadedChunk.cityObjects[i].cityObjectPart; + loadedChunk.cityObjectParts[partid].pos = pos; + loadedChunk.cityObjectParts[partid].model = model; + } + + string newChunkPath = System.IO.Path.ChangeExtension(loadedChunkPath, "_new.chunk_pc"); + if (System.IO.File.Exists(newChunkPath)) + { + System.IO.File.Delete(newChunkPath); + } + System.IO.File.Copy(loadedChunkPath, newChunkPath); + chunkUnloader.PatchChunk(loadedChunk, newChunkPath); + + } +} diff --git a/autoload/ChunkLoader.cs b/autoload/ChunkLoader.cs new file mode 100644 index 0000000..1cc2cda --- /dev/null +++ b/autoload/ChunkLoader.cs @@ -0,0 +1,690 @@ +using Godot; +using System; +using System.IO; + +public class CityObjectPart +{ + // at first + public Vector3 pos; + public uint model; +} +public class CityObject +{ + // second + public Vector3 cull_max; + public Vector3 cull_min; + public float cull_distance; + public uint flags; // 11th bit will fix transparent textures. + public uint unk1; + public uint cityObjectPart; + + // third + public string name; +} + +// --- Model Buffer +public class ModelBuffer +{ + // Each of these have 1 ibuffer and 1 or more vbuffers + public uint type; // 0 is on chunk, 7 is in g_chunk + public uint vertBufferCount; // 1 on physmodels, >1 on rendermodels + public uint indexCount; + public VertBuffer[] vertBuffers; +} + +public class VertBuffer +{ + public uint unk2BCount; + public uint uvSetCount; + public uint vertSize; + public uint vertCount; +} + +/* --- Example ModelBuffer Content +// Physmodel +ModelBuffer +{ + uint type = 0 // 0 means physmodel. + uint indBufferSize = 112 + uint vertBufferCount = 1 // Always just 1 on physmodels. + VertBuffer[] vertBuffers + [ + VertBuffer 0 + { + uint unk2BCount = 0 // Unused on physmodel. + uint uvSetCount = 0 // Unused on physmodel. + uint vertSize = 12 // Vert position takes 12B. + uint vertCount = 36 + } + ] +} + +// Viewmodel +ModelBuffer +{ + uint type = 7 // 7 means viewmodel + uint indBufferSize = 2785 + uint vertBufferCount = 8 + VertBuffer[] vertBuffers + [ + // VertBuffer for each combination of unk2BCount and uvSetCount. + + VertBuffer 0 + { + uint unk2BCount = 1 // 2B + uint uvSetCount = 1 // 4B + uint vertSize = 18 // 12B + above + uint vertCount = 123 + } + VertBuffer 1 + { + uint unk2BCount = 1 + uint uvSetCount = 2 + uint vertSize = 22 + uint vertCount = 52 + } + VertBuffer 2 + { + uint unk2BCount = 2 + uint uvSetCount = 2 + uint vertSize = 24 + uint vertCount = 420 + } + ... + ] +} +*/ + +public class RenderModel +{ + public Vector3 bboxMin; + public Vector3 bboxMax; + public uint submeshCount = uint.MaxValue; + public uint unk2_count = uint.MaxValue; + public RenderModelSubmesh[] submeshes; + //public RenderModelUnk2[] unk2s +} + +public class RenderModelSubmesh +{ + public uint vertBuffer; + public uint indexOffset; + public uint vertOffset; + public uint indexCount; + public uint vertCount; + public uint material; +} + +public class Material +{ + public uint textureCount; + public uint[] textures; + public uint shaderFlagCount; +} + +// --- The chunk + +public class CPUChunk +{ + public uint MAGIC; + public uint VERSION; + public uint cityObjectCount; + + public string[] texList; + public uint texCount; + + public uint renderModelCount; + public uint cityObjectPartCount; + public uint modelBufferCount; + public uint unknownCount3; + public uint unknownCount4; + + public CityObjectPart[] cityObjectParts; + + public uint unknownCount5; + public uint unknownCount6; + public uint unknownCount7; + public uint unknownCount8; + + public uint moppSize; + + public ModelBuffer[] modelBuffers; + public uint g_chunkVBufCount; + + public Material[] materials; + public uint materialCount; + public uint shaderParamCount; + public uint matUnk2Count; + public uint matUnk3Count; + + public RenderModel[] renderModels; + public CityObject[] cityObjects; + + // offsets used when patching chunk + public uint cityObjectPartOff; + public uint cityObjectOff; +} + +public class ChunkLoader : Node +{ + static uint MAGIC = 0xBBCACA12; + static uint VERSION = 121; + + /* + * LoadChunk - parses content from .chunk_pc files + * TODO: a lot. + * + */ + public CPUChunk LoadChunk(string filepath) + { + GD.Print(filepath); + + if (!System.IO.File.Exists(filepath)) + { + GD.PushWarning("ChunkLoader.LoadChunk(): File doesn't exist! " + filepath); + return null; + } + + using (FileStream fs = System.IO.File.OpenRead(filepath)) + { + BinaryReader br = new BinaryReader(fs); + CPUChunk chunk = new CPUChunk(); + + chunk.MAGIC = br.ReadUInt32(); + chunk.VERSION = br.ReadUInt32(); + + if (chunk.MAGIC != MAGIC) + { + GD.PushWarning("Unknown Magic! " + filepath); + return null; + } + if (chunk.VERSION != VERSION) + { + GD.PushWarning("Unknown Version: " + chunk.VERSION.ToString() + "! " + filepath); + return null; + } + + fs.Seek(0x94, 0); + chunk.cityObjectCount = br.ReadUInt32(); + + fs.Seek(256, 0); + + // --- Texture List --- // + chunk.texCount = br.ReadUInt32(); + chunk.texList = new string[chunk.texCount]; + fs.Seek(chunk.texCount * 4, SeekOrigin.Current); + + for (int i = 0; i < chunk.texCount; i++) + { + string text = ""; + while (true) + { + char temp = br.ReadChar(); + if (temp == 0) { break; } + text += temp; + } + chunk.texList[i] = text; + } + + // byte align + while ((fs.Position & 0xf) != 0) { fs.Seek(1, SeekOrigin.Current); } + + // --- Model Header --- // + chunk.renderModelCount = br.ReadUInt32(); + chunk.cityObjectPartCount = br.ReadUInt32(); + chunk.modelBufferCount = br.ReadUInt32(); + chunk.unknownCount3 = br.ReadUInt32(); + chunk.unknownCount4 = br.ReadUInt32(); + fs.Seek(12, SeekOrigin.Current); + + // --- Unknown Viewmodel Related --- // + // 24B + fs.Seek(24 * chunk.renderModelCount, SeekOrigin.Current); + + // byte align + while ((fs.Position & 0xf) != 0) { fs.Seek(1, SeekOrigin.Current); } + + // --- City Objects --- // + chunk.cityObjectPartOff = (uint)fs.Position; + chunk.cityObjectParts = new CityObjectPart[chunk.cityObjectPartCount]; + // 96B + for (int i = 0; i < chunk.cityObjectPartCount; i++) + { + CityObjectPart temp = new CityObjectPart(); + temp.pos = new Vector3(-br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); + + fs.Seek(76, SeekOrigin.Current); + temp.model = br.ReadUInt32(); + fs.Seek(4, SeekOrigin.Current); + chunk.cityObjectParts[i] = temp; + } + + // --- Unknown3 --- // + fs.Seek(100 * chunk.unknownCount3, SeekOrigin.Current); + + // byte align + while ((fs.Position & 0xf) != 0) { fs.Seek(1, SeekOrigin.Current); } + + // --- Unknown4 --- // + fs.Seek(52 * chunk.unknownCount4, SeekOrigin.Current); + + // byte align + while ((fs.Position & 0xf) != 0) { fs.Seek(1, SeekOrigin.Current); } + + // --- Unknown5 --- // + chunk.unknownCount5 = br.ReadUInt32(); + // 12B + fs.Seek(12 * chunk.unknownCount5, SeekOrigin.Current); + + // --- Unknown6 --- // + chunk.unknownCount6 = br.ReadUInt32(); + // 3B + fs.Seek(3 * chunk.unknownCount6, SeekOrigin.Current); + + // --- Unknown7 --- // + chunk.unknownCount7 = br.ReadUInt32(); + // 4B + fs.Seek(4 * chunk.unknownCount7, SeekOrigin.Current); + + // --- Unknown8 --- // + chunk.unknownCount8 = br.ReadUInt32(); + // 12B + fs.Seek(12 * chunk.unknownCount8, SeekOrigin.Current); + + // byte align + while ((fs.Position & 0xf) != 0) + { + fs.Seek(1, SeekOrigin.Current); + } + + // --- Havok Mopp Collision tree --- // + chunk.moppSize = br.ReadUInt32(); + + // byte align + while ((fs.Position & 0xf) != 0) { fs.Seek(1, SeekOrigin.Current); } + + fs.Seek(chunk.moppSize, SeekOrigin.Current); + fs.Seek(24, SeekOrigin.Current); + + // byte align + while ((fs.Position & 0xf) != 0) { fs.Seek(1, SeekOrigin.Current); } + + // --- Model Buffer Header --- // + chunk.modelBuffers = new ModelBuffer[chunk.modelBufferCount]; + // 20B + for (int i = 0; i < chunk.modelBufferCount; i++) + { + ModelBuffer temp = new ModelBuffer(); + temp.type = br.ReadUInt16(); + temp.vertBufferCount = br.ReadUInt16(); + temp.indexCount = br.ReadUInt32(); + fs.Seek(12, SeekOrigin.Current); + chunk.modelBuffers[i] = temp; + } + // Vertex buffer header + chunk.g_chunkVBufCount = 0; + for (int i = 0; i < chunk.modelBufferCount; i++) + { + chunk.modelBuffers[i].vertBuffers = new VertBuffer[chunk.modelBuffers[i].vertBufferCount]; + // 16B + for (int ii = 0; ii < chunk.modelBuffers[i].vertBufferCount; ii++) + { + VertBuffer temp = new VertBuffer(); + fs.Seek(2, SeekOrigin.Current); + temp.vertSize = br.ReadUInt16(); + temp.vertCount = br.ReadUInt32(); + fs.Seek(8, SeekOrigin.Current); + chunk.modelBuffers[i].vertBuffers[ii] = temp; + + if (chunk.modelBuffers[i].type == 0) + { + chunk.g_chunkVBufCount += 1; + } + } + } + chunk.g_chunkVBufCount = 0; + for (int i = 0; i < chunk.modelBufferCount; i++) + { + if (chunk.modelBuffers[i].type == 0) + { + chunk.g_chunkVBufCount += 1; + } + } + // byte align + while ((fs.Position & 0xf) != 0) { fs.Seek(1, SeekOrigin.Current); } + + // --- Physics Models --- // + for (int i = 0; i < chunk.modelBufferCount; i++) + { + if (chunk.modelBuffers[i].type == 7) + { + // Vertices + fs.Seek(12 * chunk.modelBuffers[i].vertBuffers[0].vertCount, SeekOrigin.Current); + + // byte align + while ((fs.Position & 0xf) != 0) { fs.Seek(1, SeekOrigin.Current); } + + // Indices + fs.Seek(2 * chunk.modelBuffers[i].indexCount, SeekOrigin.Current); + + // byte align + while ((fs.Position & 0xf) != 0) { fs.Seek(1, SeekOrigin.Current); } + } + } + + // --- Materials --- // + + //GD.Print("mat Count: ", chunk.materialCount); + chunk.materialCount = br.ReadUInt32(); + + // byte align + while ((fs.Position & 0xf) != 0) { fs.Seek(1, SeekOrigin.Current); } + + chunk.shaderParamCount = br.ReadUInt32(); + fs.Seek(8, SeekOrigin.Current); + chunk.matUnk2Count = br.ReadUInt32(); + fs.Seek(4, SeekOrigin.Current); + + chunk.materials = new Material[chunk.materialCount]; + // 24B + for (int i = 0; i < chunk.materialCount; i++) + { + Material temp = new Material(); + fs.Seek(12, SeekOrigin.Current); + temp.shaderFlagCount = br.ReadUInt16(); + temp.textureCount = br.ReadUInt16(); + fs.Seek(8, SeekOrigin.Current); + chunk.materials[i] = temp; + } + + // Bit flags, maybe? Messing with these toggled uv repeat on for ultor flags. + for (int i = 0; i < chunk.materialCount; i++) + { + for (int ii = 0; ii < chunk.materials[i].shaderFlagCount; ii++) + { + fs.Seek(6, SeekOrigin.Current); + } + if (chunk.materials[i].shaderFlagCount % 2 != 0) + { + fs.Seek(2, SeekOrigin.Current); + } + } + + // Messing with these break shaders. + // 16B + for (int i = 0; i < chunk.materialCount; i++) + { + fs.Seek(16, SeekOrigin.Current); + } + + // byte align + while ((fs.Position & 0xf) != 0) { fs.Seek(1, SeekOrigin.Current); } + + // Shader Floats + // Mostly colors, sometimes affects scrolling texture speed and probably more things. + // 4B single float + for (int i = 0; i < chunk.shaderParamCount; i++) + { + fs.Seek(4, SeekOrigin.Current); + } + + // Material Texture IDs + // 64B + for (int i = 0; i < chunk.materialCount; i++) + { + fs.Seek(64, SeekOrigin.Current); + } + + // Material Unknown 2 + chunk.matUnk3Count = 0; + // 16B + for (int i = 0; i < chunk.matUnk2Count; i++) + { + fs.Seek(8, SeekOrigin.Current); + chunk.matUnk3Count += br.ReadUInt16(); + fs.Seek(6, SeekOrigin.Current); + } + + // Material Unknown 3 + // 4B + for (int i = 0; i < chunk.matUnk3Count; i++) + { + fs.Seek(4, SeekOrigin.Current); + } + + // --- Render Models --- // + chunk.renderModels = new RenderModel[chunk.renderModelCount]; + GD.Print("RenderModelCount: ", chunk.renderModelCount); + GD.Print("RenderModels Off: ", fs.Position.ToString("X")); + for (int i = 0; i < chunk.renderModelCount; i++) + { + //GD.Print("got here"); + + + RenderModel temp = new RenderModel(); + + temp.bboxMin = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); + temp.bboxMax = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); + + fs.Seek(8, SeekOrigin.Current); + + if (br.ReadUInt32() == 0) { temp.submeshCount = 0; } + if (br.ReadUInt32() == 0) { temp.unk2_count = 0; } + + // byte align + while ((fs.Position & 0xf) != 0) { fs.Seek(1, SeekOrigin.Current); } + + // Get Submesh counts + if (temp.submeshCount != 0) + { + fs.Seek(2, SeekOrigin.Current); + temp.submeshCount = br.ReadUInt16(); + fs.Seek(8, SeekOrigin.Current); + // byte align + while ((fs.Position & 0xf) != 0) { fs.Seek(1, SeekOrigin.Current); } + } + if (temp.unk2_count != 0) + { + fs.Seek(2, SeekOrigin.Current); + temp.unk2_count = br.ReadUInt16(); + fs.Seek(8, SeekOrigin.Current); + // byte align + while ((fs.Position & 0xf) != 0) { fs.Seek(1, SeekOrigin.Current); } + } + + // Get Submeshes + temp.submeshes = new RenderModelSubmesh[temp.submeshCount]; + for (int ii = 0; ii < temp.submeshCount; ii++) + { + RenderModelSubmesh tempSubmesh = new RenderModelSubmesh(); + tempSubmesh.vertBuffer = br.ReadUInt32(); + tempSubmesh.indexOffset = br.ReadUInt32(); + tempSubmesh.vertOffset = br.ReadUInt32(); + tempSubmesh.indexCount = br.ReadUInt16(); + tempSubmesh.material = br.ReadUInt16(); + temp.submeshes[ii] = tempSubmesh; + } + // Unk2 is unkwnown format. If the model uses unk2, the above submodels are garbage too! + // I assume they have something to do with models at the end of the file. + for (int ii = 0; ii < temp.unk2_count; ii++) + { + fs.Seek(16, SeekOrigin.Current); + } + chunk.renderModels[i] = temp; + } + + // CityObjects + // 80B + chunk.cityObjectOff = (uint)fs.Position; + chunk.cityObjects = new CityObject[chunk.cityObjectCount]; + for (int i = 0; i < chunk.cityObjectCount; i++) + { + CityObject cobj = new CityObject(); + cobj.cull_max = new Vector3( + br.ReadSingle(), + br.ReadSingle(), + br.ReadSingle() + ); + fs.Seek(4, SeekOrigin.Current); + cobj.cull_min = new Vector3( + br.ReadSingle(), + br.ReadSingle(), + br.ReadSingle() + ); + cobj.cull_distance = br.ReadSingle(); + fs.Seek(16, SeekOrigin.Current); + cobj.flags = br.ReadUInt32(); + cobj.unk1 = br.ReadUInt32(); + fs.Seek(8, SeekOrigin.Current); + cobj.cityObjectPart = br.ReadUInt32(); + fs.Seek(12, SeekOrigin.Current); + + chunk.cityObjects[i] = cobj; + } + + // Names + for (int i = 0; i < chunk.cityObjectCount; i++) + { + string text = ""; + while (true) + { + char temp = br.ReadChar(); + if (temp == 0) { break; } + text += temp; + } + chunk.cityObjects[i].name = text; + } + GD.Print("end: ", fs.Position.ToString("X")); + GD.Print("cobj: ", chunk.cityObjectPartCount); + GD.Print("cull: ", chunk.cityObjectCount); + + uint unkmodel_cityobjs = 0; + for (int i = 0; i < chunk.cityObjectPartCount; i++) + { + uint modelid = chunk.cityObjectParts[i].model; + + if (chunk.renderModels[modelid].unk2_count > 0) + { + unkmodel_cityobjs++; + } + } + GD.Print("unkmodl: ", unkmodel_cityobjs); + + + return chunk; + } + } + + /* + * LoadGPUChunk - unpacks models from .g_chunk_pc files + * TODO: Instead of spawning nodes here, return meshes or meshinstances + * TODO: Figure out models at the end of the file. After that, g_chunks are 100% done! + */ + + public void LoadGPUChunk(CPUChunk chunk, string filepath) + { + if (!System.IO.File.Exists(filepath)) + { + GD.PushWarning("ChunkLoader.LoadGPUChunk(): File doesn't exist! " + filepath); + return;// null; + } + + using (FileStream fs = System.IO.File.OpenRead(filepath)) + { + BinaryReader br = new BinaryReader(fs); + + for (int i = 0; i < chunk.renderModelCount; i++) + { + RenderModel model = chunk.renderModels[i]; + SurfaceTool st = new SurfaceTool(); + st.Begin(Mesh.PrimitiveType.Triangles); + + // Buffer Offsets + uint iBufOffset = 0; + uint[] vBufOffsets = new uint[chunk.modelBuffers[0].vertBufferCount]; + for (int ii = 0; ii < chunk.modelBuffers[0].vertBufferCount; ii++) + { + vBufOffsets[ii] = iBufOffset; + uint vertCount = chunk.modelBuffers[0].vertBuffers[ii].vertCount; + uint vertSize = chunk.modelBuffers[0].vertBuffers[ii].vertSize; + iBufOffset += vertCount * vertSize; + // byte align + while ((iBufOffset & 0xf) != 0) { iBufOffset += 1; } + } + + // Buffers + uint totalVertCount = 0; + for (int ii = 0; ii < model.submeshCount; ii++) + { + // Skip models that use unk_2 + if (model.unk2_count != 0) continue; + + uint vertBufID = model.submeshes[ii].vertBuffer; + uint vertSize = chunk.modelBuffers[0].vertBuffers[vertBufID].vertSize; + + uint indexOffset = iBufOffset + model.submeshes[ii].indexOffset * 2; + uint vertexOffset = vBufOffsets[vertBufID] + model.submeshes[ii].vertOffset * vertSize; + + + // Get VertCount (it isn't stored explicitly so gotta pull it if from indices) + fs.Seek(indexOffset, SeekOrigin.Begin); + uint tempVertCount = 0; + for (int iii = 0; iii < model.submeshes[ii].indexCount; iii++) + { + tempVertCount = (uint)Math.Max(br.ReadInt16() + 1, tempVertCount); + } + model.submeshes[ii].vertCount = tempVertCount; + + // Get Vertices + fs.Seek(vertexOffset, SeekOrigin.Begin); + for (int iii = 0; iii < model.submeshes[ii].vertCount; iii++) + { + Vector3 pos = new Vector3(-br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); + st.AddVertex(pos); + fs.Seek(vertSize - 12, SeekOrigin.Current); + } + + // Get Indices + fs.Seek(indexOffset, SeekOrigin.Begin); + for (int iii = 0; iii < model.submeshes[ii].indexCount - 2; iii++) + { + uint i0 = totalVertCount + br.ReadUInt16(); + uint i1 = totalVertCount + br.ReadUInt16(); + uint i2 = totalVertCount + br.ReadUInt16(); + fs.Seek(-4, SeekOrigin.Current); + + //GD.Print(i0, " ", i1, " ", i2); + + // degen tri + if (i0 == i1 || i0 == i2 || i1 == i2) + { + continue; + } + + // Odd faces are flipped + if ((iii % 2) == 0) + { + st.AddIndex((int)i0); + st.AddIndex((int)i1); + st.AddIndex((int)i2); + } + else + { + st.AddIndex((int)i2); + st.AddIndex((int)i1); + st.AddIndex((int)i0); + } + } + totalVertCount += tempVertCount; + } + + Mesh mesh = st.Commit(); + MeshInstance meshInstance = new MeshInstance(); + meshInstance.Mesh = mesh; + meshInstance.Name = "RenderModel" + i.ToString(); + GetNode("/root/main/chunk/rendermodels").AddChild(meshInstance); + } + } + return; + } +} diff --git a/autoload/ChunkUnloader.cs b/autoload/ChunkUnloader.cs new file mode 100644 index 0000000..0096134 --- /dev/null +++ b/autoload/ChunkUnloader.cs @@ -0,0 +1,64 @@ +using Godot; +using System; +using System.IO; + +public class ChunkUnloader : Node +{ + public void PatchChunk(CPUChunk chunk, string filepath) + { + GD.Print(filepath); + + if (!System.IO.File.Exists(filepath)) + { + GD.PushWarning("ChunkLoader.LoadChunk(): File doesn't exist! " + filepath); + return; + } + + using (FileStream fs = System.IO.File.OpenWrite(filepath)) + { + BinaryWriter bw = new BinaryWriter(fs); + + + // --- City Object Part --- // + fs.Seek(chunk.cityObjectPartOff, 0); + + // 96B + for (int i = 0; i < chunk.cityObjectPartCount; i++) + { + CityObjectPart part = chunk.cityObjectParts[i]; + + bw.Write(-(Single)part.pos.x); + bw.Write((Single)part.pos.y); + bw.Write((Single)part.pos.z); + fs.Seek(76, SeekOrigin.Current); + bw.Write((UInt32)part.model); + fs.Seek(4, SeekOrigin.Current); + } + + // City Objects + fs.Seek(chunk.cityObjectOff, 0); + + // 80B + for (int i = 0; i < chunk.cityObjectCount; i++) + { + CityObject cobj = chunk.cityObjects[i]; + bw.Write((Single)cobj.cull_max.x); + bw.Write((Single)cobj.cull_max.y); + bw.Write((Single)cobj.cull_max.z); + fs.Seek(4, SeekOrigin.Current); + bw.Write((Single)cobj.cull_min.x); + bw.Write((Single)cobj.cull_min.y); + bw.Write((Single)cobj.cull_min.z); + bw.Write((Single)cobj.cull_distance); + fs.Seek(16, SeekOrigin.Current); + bw.Write((UInt32)cobj.flags); + bw.Write((UInt32)cobj.unk1); + fs.Seek(8, SeekOrigin.Current); + bw.Write((UInt32)cobj.cityObjectPart); + fs.Seek(12, SeekOrigin.Current); + } + + return; + } + } +} diff --git a/boot.png b/boot.png new file mode 100644 index 0000000..ed75041 Binary files /dev/null and b/boot.png differ diff --git a/boot.png.import b/boot.png.import new file mode 100644 index 0000000..93d71be --- /dev/null +++ b/boot.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/boot.png-0853cbca0c90c11787730c34e1b0063a.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://boot.png" +dest_files=[ "res://.import/boot.png-0853cbca0c90c11787730c34e1b0063a.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/default_env.tres b/default_env.tres new file mode 100644 index 0000000..20207a4 --- /dev/null +++ b/default_env.tres @@ -0,0 +1,7 @@ +[gd_resource type="Environment" load_steps=2 format=2] + +[sub_resource type="ProceduralSky" id=1] + +[resource] +background_mode = 2 +background_sky = SubResource( 1 ) diff --git a/icon.ico b/icon.ico new file mode 100644 index 0000000..d5a685b Binary files /dev/null and b/icon.ico differ diff --git a/icon.png b/icon.png new file mode 100644 index 0000000..e4bfc5d Binary files /dev/null and b/icon.png differ diff --git a/icon.png.import b/icon.png.import new file mode 100644 index 0000000..a4c02e6 --- /dev/null +++ b/icon.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.png" +dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/mat/mat_spatial.tres b/mat/mat_spatial.tres new file mode 100644 index 0000000..70860e5 --- /dev/null +++ b/mat/mat_spatial.tres @@ -0,0 +1,4 @@ +[gd_resource type="SpatialMaterial" format=2] + +[resource] +albedo_color = Color( 0.529412, 0.47451, 0.47451, 1 ) diff --git a/mat/mat_temp.tres b/mat/mat_temp.tres new file mode 100644 index 0000000..3276818 --- /dev/null +++ b/mat/mat_temp.tres @@ -0,0 +1,11 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=2] + +[ext_resource path="res://mat/shad_temp.tres" type="Shader" id=1] + +[resource] +shader = ExtResource( 1 ) +shader_param/Hardness = null +shader_param/SpecularPower = 1.0 +shader_param/Diffuse_Color = Color( 1, 0.945098, 0.341176, 1 ) +shader_param/Specular_Color = Color( 0.309804, 0.309804, 0.309804, 1 ) +shader_param/SpecularPower2 = null diff --git a/mat/screen_pixel_outline.shader b/mat/screen_pixel_outline.shader new file mode 100644 index 0000000..ded8285 --- /dev/null +++ b/mat/screen_pixel_outline.shader @@ -0,0 +1,42 @@ +shader_type spatial; +render_mode unshaded; + +uniform sampler2D ScreenTexture; +uniform vec4 OutlineColor : hint_color = vec4(1); + +// turn the 2x2 quad vertex locations into screen positions +void vertex() +{ + POSITION = vec4(VERTEX, 1.0); +} + +void fragment() +{ + ALBEDO = OutlineColor.rgb; + + // read screen texture produced by the outline viewport + vec4 screen_tex = texture( ScreenTexture, SCREEN_UV ); + + // compute pixel size + float p_w = 1.0/ float(VIEWPORT_SIZE.x); + float p_h = 1.0/ float(VIEWPORT_SIZE.y); + + // sample neighborhood around this fragment + float neighbourhood = 0.0; + neighbourhood += texture( ScreenTexture, SCREEN_UV+vec2( -p_w, 0.0 ) ).a; + neighbourhood += texture( ScreenTexture, SCREEN_UV+vec2( +p_w, 0.0 ) ).a; + neighbourhood += texture( ScreenTexture, SCREEN_UV+vec2( 0.0, -p_h ) ).a; + neighbourhood += texture( ScreenTexture, SCREEN_UV+vec2( 0.0, +p_h ) ).a; + + // if our original fragment was transparent _but_ something was + // in the immediate neighbourhood around that fragment we will + // want to render as a solid pixel. this creates the outline. + if ( screen_tex.a < 0.05 && neighbourhood > 0.0 ) + { + ALPHA = 1.0; + } + else + { + ALPHA = 0.0; + } +} diff --git a/mat/shad_temp.tres b/mat/shad_temp.tres new file mode 100644 index 0000000..3ed93d8 --- /dev/null +++ b/mat/shad_temp.tres @@ -0,0 +1,203 @@ +[gd_resource type="Shader" format=2] + +[resource] +code = "shader_type spatial; +render_mode cull_disabled, specular_phong; + +uniform float Hardness; +uniform float SpecularPower; +uniform vec4 Diffuse_Color : hint_color; +uniform sampler2D Texture4; +uniform sampler2D Texture3; +uniform sampler2D Texture2; +uniform sampler2D Texture1; +uniform vec4 Specular_Color : hint_color; +uniform float SpecularPower2; + + + +void vertex() { +// Output:0 + +} + +void fragment() { +// ScalarUniform:7 + float n_out7p0 = Hardness; + +// Scalar:6 + float n_out6p0 = 1.000000; + +// ScalarUniform:5 + float n_out5p0 = SpecularPower; + +// ScalarOp:4 + float n_out4p0 = n_out6p0 / n_out5p0; + +// ScalarOp:3 + float n_out3p0 = n_out7p0 * n_out4p0; + +// ScalarOp:18 + float n_out18p0 = n_out7p0 * n_out3p0; + +// Output:0 + SPECULAR = n_out18p0; + +} + +void light() { +// Input:86 + vec3 n_out86p0 = ALBEDO; + +// Input:127 + vec3 n_out127p0 = ATTENUATION; + +// VectorOp:128 + vec3 n_out128p0 = n_out86p0 * n_out127p0; + +// ColorUniform:107 + vec3 n_out107p0 = Diffuse_Color.rgb; + float n_out107p1 = Diffuse_Color.a; + +// VectorOp:106 + vec3 n_out106p0 = n_out107p0 * vec3(n_out107p1); + +// TextureUniform:126 + vec3 n_out126p0; + float n_out126p1; + { + vec4 n_tex_read = texture(Texture4, UV.xy); + n_out126p0 = n_tex_read.rgb; + n_out126p1 = n_tex_read.a; + } + +// TextureUniform:125 + vec3 n_out125p0; + float n_out125p1; + { + vec4 n_tex_read = texture(Texture3, UV.xy); + n_out125p0 = n_tex_read.rgb; + n_out125p1 = n_tex_read.a; + } + +// VectorOp:115 + vec3 n_out115p0 = n_out126p0 * n_out125p0; + +// TextureUniform:124 + vec3 n_out124p0; + float n_out124p1; + { + vec4 n_tex_read = texture(Texture2, UV.xy); + n_out124p0 = n_tex_read.rgb; + n_out124p1 = n_tex_read.a; + } + +// VectorOp:110 + vec3 n_out110p0 = n_out115p0 * n_out124p0; + +// TextureUniform:123 + vec3 n_out123p0; + float n_out123p1; + { + vec4 n_tex_read = texture(Texture1, UV.xy); + n_out123p0 = n_tex_read.rgb; + n_out123p1 = n_tex_read.a; + } + +// VectorOp:114 + vec3 n_out114p0 = n_out110p0 * n_out123p0; + +// VectorOp:109 + vec3 n_out109p0 = n_out106p0 * n_out114p0; + +// VectorOp:91 + vec3 n_out91p0 = n_out128p0 * n_out109p0; + +// VectorOp:90 + vec3 n_in90p1 = vec3(0.00000, 0.00000, 0.00000); + vec3 n_out90p0 = n_out91p0 + n_in90p1; + +// Input:74 + vec3 n_out74p0 = LIGHT; + +// Input:71 + vec3 n_out71p0 = NORMAL; + +// DotProduct:68 + float n_out68p0 = dot(n_out74p0, n_out71p0); + +// ScalarOp:69 + float n_in69p1 = 0.00000; + float n_out69p0 = max(n_out68p0, n_in69p1); + +// Input:76 + vec3 n_out76p0 = LIGHT_COLOR; + +// VectorOp:77 + vec3 n_out77p0 = vec3(n_out69p0) * n_out76p0; + +// VectorOp:75 + vec3 n_out75p0 = n_out90p0 * n_out77p0; + +// Input:95 + vec3 n_out95p0 = DIFFUSE_LIGHT; + +// VectorOp:96 + vec3 n_out96p0 = n_out75p0 + n_out95p0; + +// Input:88 + vec3 n_out88p0 = VIEW; + +// VectorFunc:93 + vec3 n_out93p0 = -(n_out88p0); + +// VectorOp:79 + vec3 n_out79p0 = reflect(n_out93p0, n_out71p0); + +// DotProduct:82 + float n_out82p0 = dot(n_out74p0, n_out79p0); + +// ScalarOp:83 + float n_in83p1 = 0.00000; + float n_out83p0 = max(n_out82p0, n_in83p1); + +// ScalarOp:78 + float n_in78p1 = 40.00000; + float n_out78p0 = pow(n_out83p0, n_in78p1); + +// VectorOp:84 + vec3 n_out84p0 = n_out76p0 * vec3(n_out78p0); + +// Input:98 + vec3 n_out98p0 = SPECULAR_LIGHT; + +// VectorOp:97 + vec3 n_out97p0 = n_out84p0 + n_out98p0; + +// ColorUniform:108 + vec3 n_out108p0 = Specular_Color.rgb; + float n_out108p1 = Specular_Color.a; + +// VectorOp:101 + vec3 n_out101p0 = n_out108p0 * vec3(n_out108p1); + +// ScalarUniform:104 + float n_out104p0 = SpecularPower2; + +// Scalar:105 + float n_out105p0 = 1.000000; + +// VectorOp:103 + vec3 n_out103p0 = vec3(n_out104p0) / vec3(n_out105p0); + +// VectorOp:102 + vec3 n_out102p0 = n_out101p0 + n_out103p0; + +// VectorOp:100 + vec3 n_out100p0 = n_out97p0 * n_out102p0; + +// Output:0 + DIFFUSE_LIGHT = n_out96p0; + SPECULAR_LIGHT = n_out100p0; + +}" diff --git a/mat/sr2_chunk028_terminal02.g_peg_pc b/mat/sr2_chunk028_terminal02.g_peg_pc new file mode 100644 index 0000000..e41d231 Binary files /dev/null and b/mat/sr2_chunk028_terminal02.g_peg_pc differ diff --git a/mat/sr2_chunk135.chunk_pc b/mat/sr2_chunk135.chunk_pc new file mode 100644 index 0000000..b8e673d Binary files /dev/null and b/mat/sr2_chunk135.chunk_pc differ diff --git a/mono_crash.0.0.json b/mono_crash.0.0.json new file mode 100644 index 0000000..b2aa49f --- /dev/null +++ b/mono_crash.0.0.json @@ -0,0 +1,320 @@ +{ + "protocol_version" : "0.0.6", + "configuration" : { + "version" : "(6.12.0) ((no/6051b710)", + "tlc" : "normal", + "sigsgev" : "altstack", + "notifications" : "epoll", + "architecture" : "amd64", + "disabled_features" : "none", + "smallconfig" : "disabled", + "bigarrays" : "disabled", + "softdebug" : "enabled", + "interpreter" : "enabled", + "llvm_support" : "disabled", + "suspend" : "preemptive" + }, + "memory" : { + "minor_gc_time" : "13580", + "major_gc_time" : "0", + "minor_gc_count" : "1", + "major_gc_count" : "0", + "major_gc_time_concurrent" : "0" + }, + "threads" : [ + { + "is_managed" : false, + "offset_free_hash" : "0x0", + "offset_rich_hash" : "0x0", + "crashed" : false, + "native_thread_id" : "0x7fe55cffe640", + "thread_info_addr" : "0x7fe548000b60", + "thread_name" : "Debugger agent", + "ctx" : { + "IP" : "0x7fe5824fc12f", + "SP" : "0x7fe55cffd9a0", + "BP" : "0x23" + }, + "unmanaged_frames" : [ + { + "is_managed" : "false", + "native_address" : "0xff3b2b", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x118c54e", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x1195217", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x100276a", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x7fe582401dc0", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x7fe5824fc12f", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x1061964", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x1073972", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x1191ad7", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x7fe58244c822", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x7fe5823ec450", + "native_offset" : "0x00000" + } + + ] + }, + { + "is_managed" : false, + "offset_free_hash" : "0x0", + "offset_rich_hash" : "0x0", + "crashed" : true, + "native_thread_id" : "0x7fe5822847c0", + "thread_info_addr" : "0x785a140", + "thread_name" : "Godot_v3.5-stab", + "ctx" : { + "IP" : "0x12eabb5", + "SP" : "0x7fff8594d620", + "BP" : "0x7fff8594d6a0" + }, + "unmanaged_frames" : [ + { + "is_managed" : "false", + "native_address" : "0xff3b2b", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x118c54e", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x1195344", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x10033b5", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x10035b9", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0xff5c6f", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x100d210", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x7fe582401dc0", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x12eabb5", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x134cc86", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x131737d", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x12ef4e7", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x350ec76", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x12602aa", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x1274941", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0xf2597e", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x7fe5823eceb0", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x7fe5823ecf60", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0xf2a34e", + "native_offset" : "0x00000" + } + + ] + }, + { + "is_managed" : false, + "offset_free_hash" : "0x0", + "offset_rich_hash" : "0x0", + "crashed" : false, + "native_thread_id" : "0x7fe56434f640", + "thread_info_addr" : "0x7fe554000b60", + "thread_name" : "Finalizer", + "ctx" : { + "IP" : "0x7fe5824493ba", + "SP" : "0x7fe56434ec20", + "BP" : "(nil)" + }, + "unmanaged_frames" : [ + { + "is_managed" : "false", + "native_address" : "0xff3b2b", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x118c54e", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x1195217", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x100276a", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x7fe582401dc0", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x7fe5824493ba", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x7fe582454848", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x10bf408", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x1191ad7", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x7fe58244c822", + "native_offset" : "0x00000" + } +, + { + "is_managed" : "false", + "native_address" : "0x7fe5823ec450", + "native_offset" : "0x00000" + } + + ] + } + ] +} \ No newline at end of file diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..de17eeb --- /dev/null +++ b/project.godot @@ -0,0 +1,40 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=4 + +[application] + +config/name="sr2_chonker" +run/main_scene="res://scenes/main.tscn" +boot_splash/image="res://boot.png" +boot_splash/bg_color=Color( 1, 1, 1, 1 ) +config/icon="res://icon.png" +config/windows_native_icon="res://icon.ico" + +[autoload] + +ChunkLoader="*res://autoload/ChunkLoader.cs" +ChunkHandler="*res://autoload/ChunkHandler.cs" +ChunkEditor="*res://autoload/ChunkEditor.gd" + +[editor_plugins] + +enabled=PoolStringArray( ) + +[gui] + +common/drop_mouse_on_gui_input_disabled=true + +[physics] + +common/enable_pause_aware_picking=true + +[rendering] + +environment/default_environment="res://default_env.tres" diff --git a/scenes/common/scripts/camera.gd b/scenes/common/scripts/camera.gd new file mode 100644 index 0000000..ca7edde --- /dev/null +++ b/scenes/common/scripts/camera.gd @@ -0,0 +1,58 @@ +extends Spatial + +var look_sensitivity = Vector2(.005, .005) +var move_sensitivity = .5 + +var look_delta: Vector2 +var fly_active = false + +onready var pivot = $pivot +onready var cam = $pivot/cam + + +func _ready(): + ChunkEditor.cam = self + +func _input(event): + if event is InputEventMouseMotion: + look_delta += event.relative * look_sensitivity + get_viewport().set_input_as_handled() + elif event is InputEventMouseButton: + if event.button_index == BUTTON_WHEEL_UP: cam.transform.origin.z *= .9 + elif event.button_index == BUTTON_WHEEL_DOWN: cam.transform.origin.z /= .9 + +func _process(delta): + if Input.is_mouse_button_pressed(3): + Input.mouse_mode = Input.MOUSE_MODE_CAPTURED + + # Mouse Drag Move + if Input.is_key_pressed(KEY_SHIFT): + var dir = Vector3.ZERO + dir -= cam.global_transform.basis.x * look_delta.x + dir += cam.global_transform.basis.y * look_delta.y + + dir *= cam.transform.origin.z + translation += dir * move_sensitivity + + # Mouse Drag Rotate + else: + rotate_y(look_delta.x) + pivot.rotate_x(look_delta.y) + if pivot.rotation.x > 1.5: + pivot.rotation.x = 1.5 + if pivot.rotation.x < -1.5: + pivot.rotation.x = -1.5 + + # WASD move + var dir = Vector3.ZERO + if Input.is_key_pressed(KEY_W): dir -= cam.global_transform.basis.z + if Input.is_key_pressed(KEY_S): dir += cam.global_transform.basis.z + if Input.is_key_pressed(KEY_A): dir -= cam.global_transform.basis.x + if Input.is_key_pressed(KEY_D): dir += cam.global_transform.basis.x + + dir *= cam.transform.origin.z * .1 + translation += dir * move_sensitivity + + else: + Input.mouse_mode = Input.MOUSE_MODE_VISIBLE + look_delta = Vector2.ZERO diff --git a/scenes/editor/scripts/CityObjectNode.cs b/scenes/editor/scripts/CityObjectNode.cs new file mode 100644 index 0000000..049f52e --- /dev/null +++ b/scenes/editor/scripts/CityObjectNode.cs @@ -0,0 +1,19 @@ +using Godot; +using System; + +public class CityObjectNode : Spatial +{ + uint model; + + public override void _Ready() + { + + } + + public void SetModel(uint _model){ + model = _model; + } + + public uint GetModel() => model; + +} diff --git a/scenes/editor/scripts/cityobject.gd b/scenes/editor/scripts/cityobject.gd new file mode 100644 index 0000000..07c819f --- /dev/null +++ b/scenes/editor/scripts/cityobject.gd @@ -0,0 +1,61 @@ +# gityobject.gd +# for chunk editor representation of a cityobject. +# Contains: +# rendermodel stored in a MeshInstance +# TODO: physmodel + +extends Spatial + +var rendermodel_id +var cityobjpart_id +var is_highlighted = false + +func _ready(): + load_model() + +func change_model(id): + rendermodel_id = id + is_highlighted = false + if get_child(0): + get_child(0).queue_free() + load_model() + +func load_model(): + if rendermodel_id: + var rendermodel = get_node("/root/main/chunk/rendermodels/RenderModel" + str(rendermodel_id)) + + # Abort on empty mesh + if rendermodel.mesh.get_surface_count() == 0: + return + + var meshinstance = MeshInstance.new() + meshinstance.mesh = rendermodel.mesh + + # Colliders are used to select cityobj by click (Collider uses rendermodel, NOT physmodel) + meshinstance.create_trimesh_collision() + meshinstance.get_child(0).connect("input_event", self, "_input_event") + + add_child(meshinstance) + + # Material) + var mat = SpatialMaterial.new() + mat.albedo_color = Color( + fmod(randf(), .2) +.5, + fmod(randf(), .2) +.5, + fmod(randf(), .2) +.5 + ) + mat.params_cull_mode = SpatialMaterial.CULL_DISABLED + meshinstance.material_override = mat + +func _input_event(camera, event, click_position, click_normal, shape_idx): + if event is InputEventMouseButton: + if event.button_index == BUTTON_LEFT and event.is_pressed(): + print("clicked ", name) + get_node("/root/ChunkEditor")._select_cityobj(self) + +func _set_highlight(highlight: bool): + if highlight and !is_highlighted: + get_child(0).material_override.albedo_color *= 5 + elif !highlight and is_highlighted: + get_child(0).material_override.albedo_color *= .2 + is_highlighted = highlight diff --git a/scenes/editor/scripts/filedrop.gd b/scenes/editor/scripts/filedrop.gd new file mode 100644 index 0000000..28d8382 --- /dev/null +++ b/scenes/editor/scripts/filedrop.gd @@ -0,0 +1,16 @@ +extends Node + +onready var chunkhandler = get_node("/root/ChunkHandler") + +var filepath = "" + +func _ready(): + get_tree().connect("files_dropped", self, "_on_files_dropped") + +func _on_files_dropped(files, _screen): + + if len(files) != 1: + print("One file at a time!") + return + filepath = files[0] + chunkhandler.LoadChunk(filepath) diff --git a/scenes/editor/scripts/gizmo.gd b/scenes/editor/scripts/gizmo.gd new file mode 100644 index 0000000..2cec6bd --- /dev/null +++ b/scenes/editor/scripts/gizmo.gd @@ -0,0 +1,19 @@ +extends Spatial + +var target: Spatial + +onready var body_x = get_node("body_x") +onready var body_y = get_node("body_y") +onready var body_z = get_node("body_z") + +onready var rod_x = get_node("rod_x") +onready var rod_y = get_node("rod_y") +onready var rod_z = get_node("rod_z") + +var dragged = false +var start_ray = "test" +var drag_start_position = Vector2(0,0) +var original_transform = null + +func _ready(): + ChunkEditor.gizmo = self diff --git a/scenes/editor/scripts/help_toggle.gd b/scenes/editor/scripts/help_toggle.gd new file mode 100644 index 0000000..847f2e5 --- /dev/null +++ b/scenes/editor/scripts/help_toggle.gd @@ -0,0 +1,8 @@ +extends Button + +func _ready(): + connect("toggled", self, "_toggled") + +func _toggled(togg): + if togg: get_child(0).show() + else: get_child(0).hide() diff --git a/scenes/editor/scripts/menu_cityobj_selected.gd b/scenes/editor/scripts/menu_cityobj_selected.gd new file mode 100644 index 0000000..e5b306f --- /dev/null +++ b/scenes/editor/scripts/menu_cityobj_selected.gd @@ -0,0 +1,41 @@ +extends Control + +var target + +onready var namelabel = $vbox/obj_name +onready var input_posx = $vbox/pos_inputs/input_x +onready var input_posy = $vbox/pos_inputs/input_y +onready var input_posz = $vbox/pos_inputs/input_z +onready var input_mdl = $vbox/mdl_inputs/input_mdl +onready var input_mdl_ok = $vbox/mdl_inputs/input_mdl_ok + + +func _ready(): + ChunkEditor.menu_cityobj_selected = self + + input_posx.connect("text_changed", self, "_update_pos") + input_posy.connect("text_changed", self, "_update_pos") + input_posz.connect("text_changed", self, "_update_pos") + input_mdl_ok.connect("pressed", self, "_update_mdl") + +func _select(cityobj): + target = cityobj + + namelabel.text = target.name + input_posx.text = str(target.translation.x) + input_posy.text = str(target.translation.y) + input_posz.text = str(target.translation.z) + input_mdl.text = str(target.rendermodel_id) + +func _update_pos(): + var deltapos = Vector3( + float(input_posx.text), + float(input_posy.text), + float(input_posz.text) + ) + target.translation = deltapos + +func _update_mdl(): + var id = int(input_mdl.text) + target.change_model(id) + diff --git a/scenes/editor/scripts/menu_file.gd b/scenes/editor/scripts/menu_file.gd new file mode 100644 index 0000000..d3272e2 --- /dev/null +++ b/scenes/editor/scripts/menu_file.gd @@ -0,0 +1,11 @@ +extends Control + +var target + +onready var input_clear = $input_clear +onready var input_save = $input_save + + +func _ready(): + input_clear.connect("pressed", ChunkEditor, "_clear") + input_save.connect("pressed", ChunkEditor, "_save") diff --git a/scenes/editor/scripts/sr2_chunk028_terminal02.g_peg_pc b/scenes/editor/scripts/sr2_chunk028_terminal02.g_peg_pc new file mode 100644 index 0000000..e41d231 Binary files /dev/null and b/scenes/editor/scripts/sr2_chunk028_terminal02.g_peg_pc differ diff --git a/scenes/editor/scripts/sr2_chunk160_cs.chunk_pc b/scenes/editor/scripts/sr2_chunk160_cs.chunk_pc new file mode 100644 index 0000000..f2d31be Binary files /dev/null and b/scenes/editor/scripts/sr2_chunk160_cs.chunk_pc differ diff --git a/scenes/main.tscn b/scenes/main.tscn new file mode 100644 index 0000000..35a387d --- /dev/null +++ b/scenes/main.tscn @@ -0,0 +1,463 @@ +[gd_scene load_steps=17 format=2] + +[ext_resource path="res://ui/icon_help.png" type="Texture" id=1] +[ext_resource path="res://scenes/common/scripts/camera.gd" type="Script" id=2] +[ext_resource path="res://scenes/editor/scripts/help_toggle.gd" type="Script" id=3] +[ext_resource path="res://scenes/editor/scripts/menu_cityobj_selected.gd" type="Script" id=4] +[ext_resource path="res://scenes/editor/scripts/menu_file.gd" type="Script" id=5] +[ext_resource path="res://scenes/editor/scripts/gizmo.gd" type="Script" id=6] + +[sub_resource type="QuadMesh" id=3] +size = Vector2( 2, 2 ) + +[sub_resource type="Shader" id=4] +code = "//THIS SHADER MUST BE APPLIED TO A QUAD (MeshInstance) WITH A SIZE OF (2, 2) +//Extra Cull Margin on the quad should be turned up all the way! + +shader_type spatial; +render_mode unshaded; + +uniform int outline_mode : hint_range(1, 3, 1) = 3; +uniform float outline_intensity : hint_range(0, 5) = 1; +uniform bool _round = false; +uniform float outline_bias : hint_range(-10, 10) = 0; + +uniform vec4 outline_color : hint_color = vec4(0.0, 0.0, 0.0, 1.0); + +void vertex() { + POSITION = vec4(VERTEX, 1.0); +} + +void fragment() { + ALBEDO = outline_color.rgb; + + vec2 screen_size = vec2(textureSize(SCREEN_TEXTURE, 1)); + + float px = 0.5/screen_size.x; + float py = 0.5/screen_size.y; + + float d = texture(DEPTH_TEXTURE, SCREEN_UV).x; + float du = texture(DEPTH_TEXTURE, SCREEN_UV+vec2(0.0, py)).x; + float dd = texture(DEPTH_TEXTURE, SCREEN_UV+vec2(0.0, -py)).x; + float dr = texture(DEPTH_TEXTURE, SCREEN_UV+vec2(px, 0.0)).x; + float dl = texture(DEPTH_TEXTURE, SCREEN_UV+vec2(-px, 0.0)).x; + + if (outline_mode == 1){ + ALPHA = 0.0 + abs(abs(d)-abs(du)) + abs(abs(d)-abs(dd)) + abs(abs(d)-abs(dl)) + abs(abs(d)-abs(dr)); + + ALPHA *= 1000.0*outline_intensity; + } else if (outline_mode == 2) { + ALPHA = 0.0 + abs(abs(abs(d)-abs(du)) - abs(abs(d)-abs(dd))) + abs(abs(abs(d)-abs(dl)) - abs(abs(d)-abs(dr))); + + ALPHA *= 3.0*50000.0*outline_intensity; + } else if (outline_mode == 3) { + float dq = texture(DEPTH_TEXTURE, SCREEN_UV+vec2(-px, py)).x; + float de = texture(DEPTH_TEXTURE, SCREEN_UV+vec2(px, py)).x; + float dz = texture(DEPTH_TEXTURE, SCREEN_UV+vec2(-px, -py)).x; + float dc = texture(DEPTH_TEXTURE, SCREEN_UV+vec2(px, -py)).x; + + ALPHA = 0.0 + abs(abs(abs(d)-abs(du)) - abs(abs(d)-abs(dd))) + abs(abs(abs(d)-abs(dl)) - abs(abs(d)-abs(dr))) + abs(abs(abs(d)-abs(dq)) - abs(abs(d)-abs(dc))) + abs(abs(abs(d)-abs(dz)) - abs(abs(d)-abs(de))); + + ALPHA *= 50000.0*outline_intensity; + } + + ALPHA += outline_bias; + + if (_round) { + ALPHA = round(ALPHA); + } + + ALPHA *= outline_color.a; +} + +//Written by Warren Jennings" + +[sub_resource type="ShaderMaterial" id=5] +shader = SubResource( 4 ) +shader_param/outline_mode = 3 +shader_param/outline_intensity = 1.0 +shader_param/_round = false +shader_param/outline_bias = 0.0 +shader_param/outline_color = Color( 0, 0, 0, 1 ) + +[sub_resource type="CylinderMesh" id=6] +top_radius = 0.01 +bottom_radius = 0.01 +height = 1.0 +radial_segments = 4 +rings = 0 + +[sub_resource type="SpatialMaterial" id=7] +render_priority = 127 +flags_unshaded = true +flags_no_depth_test = true +albedo_color = Color( 0.917647, 0.196078, 0.309804, 1 ) + +[sub_resource type="SpatialMaterial" id=8] +render_priority = 127 +flags_unshaded = true +flags_no_depth_test = true +albedo_color = Color( 0.505882, 0.803922, 0.054902, 1 ) + +[sub_resource type="SpatialMaterial" id=9] +flags_unshaded = true +flags_no_depth_test = true +albedo_color = Color( 0.156863, 0.52549, 0.917647, 1 ) + +[sub_resource type="CylinderMesh" id=11] +top_radius = 0.0 +bottom_radius = 0.06 +height = 0.25 + +[sub_resource type="CubeMesh" id=12] +size = Vector3( 0.1, 0.01, 0.1 ) + +[sub_resource type="CylinderShape" id=13] +height = 1.2 +radius = 0.05 + +[node name="main" type="Spatial"] + +[node name="ui" type="Control" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +mouse_filter = 2 + +[node name="vbox" type="VBoxContainer" parent="ui"] +visible = false +anchor_right = 1.0 +anchor_bottom = 1.0 +mouse_filter = 2 + +[node name="RichTextLabel" type="RichTextLabel" parent="ui/vbox"] +margin_right = 1024.0 +margin_bottom = 15.0 +mouse_filter = 2 +bbcode_enabled = true +bbcode_text = "Selected Chunk: -" +text = "Selected Chunk: -" +fit_content_height = true + +[node name="dock" type="PanelContainer" parent="ui"] +visible = false +anchor_top = 1.0 +anchor_bottom = 1.0 +margin_top = -40.0 +margin_right = 74.0 +grow_vertical = 0 + +[node name="hbox" type="HBoxContainer" parent="ui/dock"] +margin_left = 7.0 +margin_top = 7.0 +margin_right = 67.0 +margin_bottom = 33.0 + +[node name="Button" type="Button" parent="ui/dock/hbox"] +margin_right = 12.0 +margin_bottom = 26.0 + +[node name="Button2" type="Button" parent="ui/dock/hbox"] +margin_left = 16.0 +margin_right = 28.0 +margin_bottom = 26.0 + +[node name="Button3" type="Button" parent="ui/dock/hbox"] +margin_left = 32.0 +margin_right = 44.0 +margin_bottom = 26.0 + +[node name="Button4" type="Button" parent="ui/dock/hbox"] +margin_left = 48.0 +margin_right = 60.0 +margin_bottom = 26.0 + +[node name="menu_cityobj_selected" type="PanelContainer" parent="ui"] +visible = false +margin_right = 360.0 +margin_bottom = 163.0 +script = ExtResource( 4 ) + +[node name="vbox" type="VBoxContainer" parent="ui/menu_cityobj_selected"] +margin_left = 7.0 +margin_top = 7.0 +margin_right = 353.0 +margin_bottom = 156.0 + +[node name="obj_name" type="Label" parent="ui/menu_cityobj_selected/vbox"] +margin_right = 346.0 +margin_bottom = 14.0 +text = "name" + +[node name="pos_title" type="HBoxContainer" parent="ui/menu_cityobj_selected/vbox"] +margin_top = 18.0 +margin_right = 346.0 +margin_bottom = 32.0 + +[node name="Label" type="Label" parent="ui/menu_cityobj_selected/vbox/pos_title"] +margin_right = 112.0 +margin_bottom = 14.0 +size_flags_horizontal = 3 +size_flags_vertical = 6 +text = "X" + +[node name="Label2" type="Label" parent="ui/menu_cityobj_selected/vbox/pos_title"] +margin_left = 116.0 +margin_right = 229.0 +margin_bottom = 14.0 +size_flags_horizontal = 3 +size_flags_vertical = 6 +text = "Y" + +[node name="Label3" type="Label" parent="ui/menu_cityobj_selected/vbox/pos_title"] +margin_left = 233.0 +margin_right = 346.0 +margin_bottom = 14.0 +size_flags_horizontal = 3 +size_flags_vertical = 6 +text = "Z" + +[node name="pos_inputs" type="HBoxContainer" parent="ui/menu_cityobj_selected/vbox"] +margin_top = 36.0 +margin_right = 346.0 +margin_bottom = 56.0 +rect_min_size = Vector2( 0, 20 ) + +[node name="input_x" type="TextEdit" parent="ui/menu_cityobj_selected/vbox/pos_inputs"] +margin_right = 112.0 +margin_bottom = 20.0 +size_flags_horizontal = 3 + +[node name="input_y" type="TextEdit" parent="ui/menu_cityobj_selected/vbox/pos_inputs"] +margin_left = 116.0 +margin_right = 229.0 +margin_bottom = 20.0 +size_flags_horizontal = 3 + +[node name="input_z" type="TextEdit" parent="ui/menu_cityobj_selected/vbox/pos_inputs"] +margin_left = 233.0 +margin_right = 346.0 +margin_bottom = 20.0 +size_flags_horizontal = 3 + +[node name="Label" type="Label" parent="ui/menu_cityobj_selected/vbox"] +margin_top = 60.0 +margin_right = 346.0 +margin_bottom = 108.0 +text = "I haven't bothered to make the gizmo work yet. You have to type the position manually. +" +autowrap = true + +[node name="mdl_inputs" type="HBoxContainer" parent="ui/menu_cityobj_selected/vbox"] +margin_top = 112.0 +margin_right = 346.0 +margin_bottom = 132.0 + +[node name="Label" type="Label" parent="ui/menu_cityobj_selected/vbox/mdl_inputs"] +margin_top = 3.0 +margin_right = 140.0 +margin_bottom = 17.0 +size_flags_horizontal = 3 +text = "Model id:" + +[node name="input_mdl" type="TextEdit" parent="ui/menu_cityobj_selected/vbox/mdl_inputs"] +margin_left = 144.0 +margin_right = 284.0 +margin_bottom = 20.0 +size_flags_horizontal = 3 + +[node name="input_mdl_ok" type="Button" parent="ui/menu_cityobj_selected/vbox/mdl_inputs"] +margin_left = 288.0 +margin_right = 346.0 +margin_bottom = 20.0 +text = "Change" + +[node name="menu_file" type="Control" parent="ui"] +anchor_right = 1.0 +anchor_bottom = 1.0 +mouse_filter = 2 +script = ExtResource( 5 ) + +[node name="input_help" type="Button" parent="ui/menu_file"] +anchor_left = 1.0 +anchor_right = 1.0 +margin_left = -36.0 +margin_top = 5.0 +margin_right = -4.0 +margin_bottom = 36.0 +toggle_mode = true +icon = ExtResource( 1 ) +icon_align = 1 +expand_icon = true +script = ExtResource( 3 ) + +[node name="PanelContainer" type="PanelContainer" parent="ui/menu_file/input_help"] +visible = false +anchor_top = 1.0 +anchor_bottom = 1.0 +margin_left = -196.0 +margin_top = 14.0 +margin_right = 28.0 +margin_bottom = 195.0 + +[node name="RichTextLabel" type="RichTextLabel" parent="ui/menu_file/input_help/PanelContainer"] +margin_left = 7.0 +margin_top = 7.0 +margin_right = 217.0 +margin_bottom = 174.0 +text = "Help: + +Hold MMB to rotate view. +Hold MMB + shift to move. +Scroll to zoom. +Press F to focus on selected. + +To get started, drag a chunkfile to this window. +(open only one at a time)" + +[node name="input_clear" type="Button" parent="ui/menu_file"] +anchor_left = 1.0 +anchor_right = 1.0 +margin_left = -86.0 +margin_top = 5.0 +margin_right = -42.0 +margin_bottom = 36.0 +text = "Clear" + +[node name="input_save" type="Button" parent="ui/menu_file"] +anchor_left = 1.0 +anchor_right = 1.0 +margin_left = -136.0 +margin_top = 5.0 +margin_right = -92.0 +margin_bottom = 36.0 +text = "Save" + +[node name="env" type="Spatial" parent="."] + +[node name="DirectionalLight" type="DirectionalLight" parent="env"] +transform = Transform( 0.727497, -0.537737, 0.426129, 0, 0.621079, 0.783748, -0.68611, -0.570174, 0.451834, 0, 0, 0 ) + +[node name="editor" type="Spatial" parent="."] + +[node name="cameraman" type="Spatial" parent="editor"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0 ) +script = ExtResource( 2 ) + +[node name="pivot" type="Spatial" parent="editor/cameraman"] + +[node name="cam" type="Camera" parent="editor/cameraman/pivot"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 5.31033 ) +cull_mask = 1048573 +current = true +near = 1.0 +far = 10000.0 + +[node name="CSGMesh" type="CSGMesh" parent="editor/cameraman/pivot/cam"] +transform = Transform( 1.08013, 0, 0, 0, 1.08013, 0, 0, 0, 1.08013, 0, 0, -1 ) +mesh = SubResource( 3 ) +material = SubResource( 5 ) + +[node name="gizmos" type="Spatial" parent="editor"] + +[node name="gizmo_translation" type="Spatial" parent="editor/gizmos"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.230934, -0.541786, -3.39796 ) +visible = false +script = ExtResource( 6 ) + +[node name="rod_x" type="CSGMesh" parent="editor/gizmos/gizmo_translation"] +transform = Transform( -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0, 1, 0.5, 0, 0 ) +layers = 255 +cast_shadow = 0 +mesh = SubResource( 6 ) +material = SubResource( 7 ) + +[node name="rod_y" type="CSGMesh" parent="editor/gizmos/gizmo_translation"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0 ) +layers = 255 +cast_shadow = 0 +mesh = SubResource( 6 ) +material = SubResource( 8 ) + +[node name="rod_z" type="CSGMesh" parent="editor/gizmos/gizmo_translation"] +transform = Transform( 1.91069e-15, -4.37114e-08, -1, -1, -4.37114e-08, 0, -4.37114e-08, 1, -4.37114e-08, 0, 0, 0.5 ) +layers = 255 +cast_shadow = 0 +mesh = SubResource( 6 ) +material = SubResource( 9 ) + +[node name="tip_x" type="CSGMesh" parent="editor/gizmos/gizmo_translation"] +transform = Transform( -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0, 1, 1.1, 0, 0 ) +layers = 255 +cast_shadow = 0 +calculate_tangents = false +mesh = SubResource( 11 ) +material = SubResource( 7 ) + +[node name="tip_y" type="CSGMesh" parent="editor/gizmos/gizmo_translation"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.1, 0 ) +layers = 255 +cast_shadow = 0 +calculate_tangents = false +mesh = SubResource( 11 ) +material = SubResource( 8 ) + +[node name="tip_z" type="CSGMesh" parent="editor/gizmos/gizmo_translation"] +transform = Transform( 1.91069e-15, -4.37114e-08, -1, -1, -4.37114e-08, 0, -4.37114e-08, 1, -4.37114e-08, 0, 0, 1.1 ) +layers = 255 +cast_shadow = 0 +calculate_tangents = false +mesh = SubResource( 11 ) +material = SubResource( 9 ) + +[node name="plane_yz" type="CSGMesh" parent="editor/gizmos/gizmo_translation"] +transform = Transform( -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0, 1, 0, 0.2, 0.2 ) +layers = 255 +cast_shadow = 0 +mesh = SubResource( 12 ) +material = SubResource( 7 ) + +[node name="plane_xz" type="CSGMesh" parent="editor/gizmos/gizmo_translation"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.2, 0, 0.2 ) +layers = 255 +cast_shadow = 0 +mesh = SubResource( 12 ) +material = SubResource( 8 ) + +[node name="plane_xy" type="CSGMesh" parent="editor/gizmos/gizmo_translation"] +transform = Transform( 1.91069e-15, -4.37114e-08, -1, -1, -4.37114e-08, 0, -4.37114e-08, 1, -4.37114e-08, 0.2, 0.2, 1.19209e-07 ) +layers = 255 +cast_shadow = 0 +mesh = SubResource( 12 ) +material = SubResource( 9 ) + +[node name="body_x" type="StaticBody" parent="editor/gizmos/gizmo_translation"] +transform = Transform( -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0, 1, 0, 0, 0 ) + +[node name="CollisionShape" type="CollisionShape" parent="editor/gizmos/gizmo_translation/body_x"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.6, 0 ) +shape = SubResource( 13 ) + +[node name="body_y" type="StaticBody" parent="editor/gizmos/gizmo_translation"] + +[node name="CollisionShape" type="CollisionShape" parent="editor/gizmos/gizmo_translation/body_y"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.6, 0 ) +shape = SubResource( 13 ) + +[node name="body_z" type="StaticBody" parent="editor/gizmos/gizmo_translation"] +transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0 ) + +[node name="CollisionShape" type="CollisionShape" parent="editor/gizmos/gizmo_translation/body_z"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.6, 0 ) +shape = SubResource( 13 ) + +[node name="chunk" type="Spatial" parent="."] + +[node name="physmodels" type="Spatial" parent="chunk"] + +[node name="not implemented in chunkloader" type="Spatial" parent="chunk/physmodels"] +visible = false + +[node name="rendermodels" type="Spatial" parent="chunk"] +visible = false + +[node name="cityobjects" type="Spatial" parent="chunk"] diff --git a/sr2_chonker.csproj b/sr2_chonker.csproj new file mode 100644 index 0000000..db88a8d --- /dev/null +++ b/sr2_chonker.csproj @@ -0,0 +1,5 @@ + + + net472 + + \ No newline at end of file diff --git a/sr2_chonker.sln b/sr2_chonker.sln new file mode 100644 index 0000000..88733cc --- /dev/null +++ b/sr2_chonker.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sr2_chonker", "sr2_chonker.csproj", "{42B9EFB3-5D5A-412F-8A48-8C39BEA83D1B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + ExportDebug|Any CPU = ExportDebug|Any CPU + ExportRelease|Any CPU = ExportRelease|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {42B9EFB3-5D5A-412F-8A48-8C39BEA83D1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {42B9EFB3-5D5A-412F-8A48-8C39BEA83D1B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {42B9EFB3-5D5A-412F-8A48-8C39BEA83D1B}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU + {42B9EFB3-5D5A-412F-8A48-8C39BEA83D1B}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU + {42B9EFB3-5D5A-412F-8A48-8C39BEA83D1B}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU + {42B9EFB3-5D5A-412F-8A48-8C39BEA83D1B}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU + EndGlobalSection +EndGlobal diff --git a/sr2_chunk135.g_chunk_pc b/sr2_chunk135.g_chunk_pc new file mode 100644 index 0000000..91645c5 Binary files /dev/null and b/sr2_chunk135.g_chunk_pc differ diff --git a/ui/icon_help.png b/ui/icon_help.png new file mode 100644 index 0000000..71c5517 Binary files /dev/null and b/ui/icon_help.png differ diff --git a/ui/icon_help.png.import b/ui/icon_help.png.import new file mode 100644 index 0000000..eef4e20 --- /dev/null +++ b/ui/icon_help.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon_help.png-04b6a7b2cb754d6fe18cf85be3288d69.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://ui/icon_help.png" +dest_files=[ "res://.import/icon_help.png-04b6a7b2cb754d6fe18cf85be3288d69.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0