diff --git a/scenes/world/DynamicMap.tscn b/scenes/world/DynamicMap.tscn index f0d63b5..8f6a7c9 100644 --- a/scenes/world/DynamicMap.tscn +++ b/scenes/world/DynamicMap.tscn @@ -33,7 +33,7 @@ script = ExtResource("2_co6fy") transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0) [node name="CSGBox3D" type="CSGBox3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.97521, -1.86909, -3.06) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 100, -1.86909, -3.06) visible = false use_collision = true size = Vector3(15.4238, 0.866943, 15.2599) @@ -41,4 +41,4 @@ size = Vector3(15.4238, 0.866943, 15.2599) [node name="Label3D" type="Label3D" parent="."] [node name="Player" parent="." instance=ExtResource("3_58gow")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.74637, 0) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 100, 0, 0) diff --git a/src/DynamicMap.gd b/src/DynamicMap.gd index c3bc69a..982c188 100644 --- a/src/DynamicMap.gd +++ b/src/DynamicMap.gd @@ -6,7 +6,11 @@ func _ready() -> void: #add_child(B3D.Load("GFX\\apache.b3d")) #add_child(X.LoadModel("res://GFX/map/Door01.x")) - add_child(X.LoadModel("res://GFX/map/DoorFrame.x")) + #var modl = X.LoadModel("res://GFX/map/DoorFrame.x") + #modl.scale.x = Constants.RoomScale + #modl.scale.y = Constants.RoomScale + #modl.scale.z = Constants.RoomScale + #add_child(modl) #DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN) @@ -14,8 +18,8 @@ func _ready() -> void: #CreateMap() IntroEnabled = true - #LoadRoomTemplates("Data/rooms.ini") - #CreateMap() + LoadRoomTemplates("Data/rooms.ini") + CreateMap() var IntroEnabled: bool var I_Zone: MapZones = MapZones.new() @@ -120,12 +124,17 @@ func CreateDoor(lvl, x:float, y:float, z:float, angle:float, room:Room, dopen = #entityType d\obj2, HIT_MAP #scaleentity(d\obj, 0.1, 0.1, 0.1) - d.frameobj.position.x = x - d.frameobj.position.y = y - d.frameobj.position.z = z d.frameobj.scale.x = Constants.RoomScale d.frameobj.scale.y = Constants.RoomScale d.frameobj.scale.z = Constants.RoomScale + + d.obj.name = str("doar ", doors.size() - 1) + parent.add_child(d.frameobj) + parent.add_child(d.obj) + + d.frameobj.global_position.x = x + d.frameobj.global_position.y = y + d.frameobj.global_position.z = z #EntityPickMode d\frameobj,2 #EntityType d\obj, HIT_MAP #EntityType d\obj2, HIT_MAP @@ -156,48 +165,55 @@ func CreateDoor(lvl, x:float, y:float, z:float, angle:float, room:Room, dopen = d.buttons[i].scale.y = 0.03 d.buttons[i].scale.z = 0.03 - if big: - d.buttons[0].position.x = x - 432.0 * Constants.RoomScale - d.buttons[0].position.y = y + 0.7 - d.buttons[0].position.z = z + 192.0 * Constants.RoomScale - d.buttons[1].position.x = x + 432.0 * Constants.RoomScale - d.buttons[1].position.y = y + 0.7 - d.buttons[1].position.z = z - 192.0 * Constants.RoomScale + if big > 0: + d.buttons[0].global_position.x = x - 432.0 * Constants.RoomScale + d.buttons[0].global_position.y = y + 0.7 + d.buttons[0].global_position.z = z + 192.0 * Constants.RoomScale + d.buttons[1].global_position.x = x + 432.0 * Constants.RoomScale + d.buttons[1].global_position.y = y + 0.7 + d.buttons[1].global_position.z = z - 192.0 * Constants.RoomScale d.buttons[0].rotation.y = 90 d.buttons[1].rotation.y = 270 else: - d.buttons[0].position.x = x + 0.6 - d.buttons[0].position.y = y + 0.7 - d.buttons[0].position.z = z - 0.1 - d.buttons[1].position.x = x - 0.6 - d.buttons[1].position.y = y + 0.7 - d.buttons[1].position.z = z + 0.1 + d.buttons[0].global_position.x = x + 0.6 + d.buttons[0].global_position.y = y + 0.7 + d.buttons[0].global_position.z = z - 0.1 + d.buttons[1].global_position.x = x - 0.6 + d.buttons[1].global_position.y = y + 0.7 + d.buttons[1].global_position.z = z + 0.1 d.buttons[1].rotation.y = 180 #EntityPickMode(d\buttons[0], 2) #EntityPickMode(d\buttons[1], 2) - d.obj.position.x = x - d.obj.position.y = y - d.obj.position.z = z + d.obj.global_position.x = x + d.obj.global_position.y = y + d.obj.global_position.z = z - d.obj.rotation.y = angle - d.frameobj.rotation.y = angle + d.obj.rotation.y = deg_to_rad(angle) + d.frameobj.rotation.y = deg_to_rad(angle) if d.obj2 != null: - d.obj2.position.x = x - d.obj2.position.y = y - d.obj2.position.z = z - - if big: - d.obj2.rotation.y = angle - else: - d.obj2.rotation.y = angle + 180 - parent.add_child(d.obj2) - - parent.add_child(d.frameobj) - parent.add_child(d.obj) + d.obj2.global_position.x = x + d.obj2.global_position.y = y + d.obj2.global_position.z = z + + var text3 = Label3D.new() + text3.position.y = 10 + text3.scale.x = 3 + text3.scale.y = 3 + text3.scale.z = 3 + text3.billboard = BaseMaterial3D.BILLBOARD_ENABLED + text3.name = "Egg" + d.obj2.add_child(text3) + d.obj2.set_script(load("res://src/stinky.gd")) + + if big > 0: + d.obj2.rotation.y = deg_to_rad(angle) + else: + d.obj2.rotation.y = deg_to_rad(angle + 180) + d.angle = angle d.open = dopen @@ -2328,18 +2344,19 @@ func FillRoom(r:Room): #r\Objects[1] = sc\ScrObj # #;[End Block] - #Case "endroom" - #;[Block] - #r\RoomDoors[0] = CreateDoor(r\zone, r\x, 0, r\z + 1136 * RoomScale, 0, r, False, True, 6) - #r\RoomDoors[0]\AutoClose = False : r\RoomDoors[0]\open = False - #FreeEntity r\RoomDoors[0]\buttons[0] : r\RoomDoors[0]\buttons[0]=0 - #FreeEntity r\RoomDoors[0]\buttons[1] : r\RoomDoors[0]\buttons[1]=0 - #;[End Block] - #Case "endroomc" - #;[Block] - #d = CreateDoor(r\zone, r\x+1024*RoomScale, 0, r\z, 0, r, False, 2, False, "") - #d\open = False : d\AutoClose = False : d\locked = True - #;[End Block] + elif rn == "endroom": + r.RoomDoors[0] = CreateDoor(r.zone, r.x, 0, r.z + 1136 * Constants.RoomScale, 0, r, false, true, 6) + r.RoomDoors[0].AutoClose = false + r.RoomDoors[0].open = false + r.RoomDoors[0].buttons[0].queue_free() + r.RoomDoors[0].buttons[0] = null + r.RoomDoors[0].buttons[1].queue_free() + r.RoomDoors[0].buttons[1] = null + elif rn == "endroomc": + var d = CreateDoor(r.zone, r.x + 1024 * Constants.RoomScale, 0, r.z, 0, r, false, 2, false, "") + d.open = false + d.AutoClose = false + d.locked = true #Case "coffin" #;[Block] #d = CreateDoor(r\zone, r\x, 0, r\z - 448.0 * RoomScale, 0, r, False, True, 2) @@ -2498,14 +2515,14 @@ func FillRoom(r:Room): r.Objects[i].scale.z = Constants.RoomScale #EntityPickMode(r\Objects[i], 2) - r.Objects[0].position.x = r.x - r.Objects[0].position.y = r.y + 190.0 * Constants.RoomScale - r.Objects[0].position.z = r.z + 374.0 * Constants.RoomScale - r.Objects[1].position.x = r.x - r.Objects[1].position.y = r.y + 230.0 * Constants.RoomScale - r.Objects[1].position.z = r.z + 374.0 * Constants.RoomScale r.obj.add_child(r.Objects[0]) r.obj.add_child(r.Objects[1]) + r.Objects[0].global_position.x = r.x + r.Objects[0].global_position.y = r.y + 190.0 * Constants.RoomScale + r.Objects[0].global_position.z = r.z + 374.0 * Constants.RoomScale + r.Objects[1].global_position.x = r.x + r.Objects[1].global_position.y = r.y + 230.0 * Constants.RoomScale + r.Objects[1].global_position.z = r.z + 374.0 * Constants.RoomScale #d = CreateDoor(r\zone, r\x - 624.0 * RoomScale, 0.0, r\z + 528.0 * RoomScale, 180, r, True) #FreeEntity (d\obj2) : d\obj2 = 0 diff --git a/src/file_parsers/X.gd b/src/file_parsers/X.gd index 43e8042..602be8a 100644 --- a/src/file_parsers/X.gd +++ b/src/file_parsers/X.gd @@ -4,6 +4,8 @@ class_name X # https://learn.microsoft.com/en-us/windows/win32/direct3d9/dx9-graphics-reference-x-file-interfaces # NOTE: adaptation of https://github.com/oguna/Blender-XFileImporter/blob/master/xfile_parser.py +static var loadCache: Dictionary + var currentFilePath = "" var majorVersion = 0 var minorVersion = 0 @@ -18,6 +20,7 @@ var file: PackedByteArray var scene = Node3D.new() var meshes: Array var materials: Array +var finalMeshes: Array const MAX_TEX_COORDS = 2 @@ -43,6 +46,31 @@ static func _CalcMinMaxPos(verts: PackedVector3Array) -> Vector3: maxZ = vert.z return Vector3(abs(minX - maxX), abs(minY - maxY), abs(minZ - maxZ)) +static func _CalcMinMaxPosTotal(finalMeshes: Array) -> Vector3: + var minX: float = 0 + var maxX: float = 0 + var minY: float = 0 + var maxY: float = 0 + var minZ: float = 0 + var maxZ: float = 0 + for mesh in finalMeshes: + var meshX = mesh.get_meta("meshWidth") + var meshY = mesh.get_meta("meshHeight") + var meshZ = mesh.get_meta("meshDepth") + if meshX < minX: + minX = meshX + if meshX > maxX: + maxX = meshX + if meshY < minY: + minY = meshY + if meshY > maxY: + maxY = meshY + if meshZ < minZ: + minZ = meshZ + if meshZ > maxZ: + maxZ = meshZ + return Vector3(abs(minX - maxX), abs(minY - maxY), abs(minZ - maxZ)) + static func MeshWidth(mesh: Node) -> float: return mesh.get_meta("meshWidth") @@ -71,7 +99,7 @@ func FindNextNonWhiteSpace(): return while true: - while p < end and (GetStringBytes(p, p + 1) == " " or GetStringBytes(p, p + 1) == "\r" or GetStringBytes(p, p + 1) == "\n"): + while p < end and (GetStringBytes(p, p + 1) == " " or GetStringBytes(p, p + 1) == "\n"): if GetStringBytes(p, p + 1) == "\n": lineNumber += 1 p += 1 @@ -90,7 +118,12 @@ static func LoadModel(filePath: String): # Do a case insensitive lookup only if we have to, it's more expensive. if file == null: - file = FileAccess.open(Utils.GetCaseiFileName(sillyPath), FileAccess.READ) + sillyPath = Utils.GetCaseiFileName(sillyPath) + file = FileAccess.open(sillyPath, FileAccess.READ) + + if loadCache.has(sillyPath): + file.close() + return loadCache.get(sillyPath).duplicate() var x = X.new() x.currentFilePath = Utils.StripFilename(sillyPath) @@ -171,8 +204,15 @@ static func LoadModel(filePath: String): meshInstance.set_meta("meshHeight", meshSize.y) meshInstance.set_meta("meshDepth", meshSize.z) + x.finalMeshes.push_back(meshInstance) mesh.parent.add_child(meshInstance) + var meshSize = _CalcMinMaxPosTotal(x.finalMeshes) + x.scene.set_meta("meshWidth", meshSize.x) + x.scene.set_meta("meshHeight", meshSize.y) + x.scene.set_meta("meshDepth", meshSize.z) + + loadCache[sillyPath] = x.scene.duplicate() return x.scene func ReadBinWord() -> int: @@ -215,8 +255,8 @@ func ReadHead(): func ParseTemplate(): var name = ReadHead() var guid = GetNextToken() - print(name) - print(guid) + #print(name) + #print(guid) while true: var s = GetNextToken() if s == "}": @@ -315,8 +355,8 @@ func ReadVector2() -> Vector2: TestForSeparator() return Vector2(x, y) -func ReadVector3() -> Vector3: - var x = -ReadFloat() +func ReadVector3(invertX:bool = false) -> Vector3: + var x = -ReadFloat() if invertX else ReadFloat() var y = ReadFloat() var z = ReadFloat() TestForSeparator() @@ -351,13 +391,15 @@ func ParseMesh(parent: Node): var mesh = XMesh.new() mesh.parent = parent meshes.push_back(mesh) - ReadHead() + var name = ReadHead() + mesh.name = name var vertCount = ReadInt() for i in range(vertCount): - mesh.verts.push_back(ReadVector3()) + mesh.verts.push_back(ReadVector3(true)) var faceCount = ReadInt() + mesh.indexCount = faceCount for i in range(faceCount): var numIndices = ReadInt() if numIndices < 3: @@ -369,7 +411,7 @@ func ParseMesh(parent: Node): while true: var objectName = GetNextToken().replace("\r", "").replace("\n", "") - print(str("\"",objectName,"\"")) + #print(str("\"",objectName,"\"")) if not objectName: assert(false, "Unexpected end of file while parsing mesh structure") elif objectName == "}": @@ -426,7 +468,7 @@ func ParseMeshNormals(mesh: XMesh): mesh.normals.push_back(ReadVector3()) var faceCount = ReadInt() - if faceCount != mesh.indices.size() / 3: + if faceCount != mesh.indexCount: assert(false, "Normal face count does not match vertex face count.") for i in range(faceCount): @@ -467,7 +509,6 @@ func ParseFrame(parent: Node = null): while true: var objectName = GetNextToken().replace("\r", "").replace("\n", "") - print(str("\"",objectName,"\"")) if not objectName: assert(false, "Unexpected end of file reached while parsing frame") return @@ -477,7 +518,8 @@ func ParseFrame(parent: Node = null): ParseFrame(node) elif objectName == "FrameTransformMatrix": # TODO: Do something with this? - print(ParseTransformationMatrix()) + ParseTransformationMatrix() + #print(ParseTransformationMatrix()) elif objectName == "Mesh": ParseMesh(node) else: @@ -500,7 +542,8 @@ func ReadRGBA() -> Color: func ParseTextureFilename(): ReadHead() - var name = GetNextToken() + var name = GetNextToken().replace("\"", "") + CheckForSemicolon() CheckForClosingBrace() if not name: push_warning("Unexpected end of file while parsing unknown segment.") @@ -541,7 +584,7 @@ func ParseMaterial(): func ParseFile(): while true: var objectName = GetNextToken().replace("\r", "").replace("\n", "") - print(str("\"",objectName,"\"")) + #print(str("\"",objectName,"\"")) if not objectName: break if objectName == "template": diff --git a/src/objects/X/XMesh.gd b/src/objects/X/XMesh.gd index 1d41f14..3d0c0c8 100644 --- a/src/objects/X/XMesh.gd +++ b/src/objects/X/XMesh.gd @@ -4,6 +4,7 @@ var parent: Node var name: String var verts: PackedVector3Array = PackedVector3Array() var indices: PackedInt32Array = PackedInt32Array() +var indexCount: int = 0 var normals: PackedVector3Array = PackedVector3Array() var normalIndices: PackedInt32Array = PackedInt32Array() var uvs: PackedVector2Array = PackedVector2Array() diff --git a/src/stinky.gd b/src/stinky.gd index 45b4d85..af937b0 100644 --- a/src/stinky.gd +++ b/src/stinky.gd @@ -1,4 +1,13 @@ extends Node3D +# for when it just isn't. + func _process(delta: float): - $Egg.text = str("ROT: ", rad_to_deg(rotation.y), "\n", get_meta("rmesh")) + $Egg.position.y = X.MeshHeight(self) + 0.5 + $Egg.scale.x = 15 + $Egg.scale.y = 15 + $Egg.scale.z = 15 + $Egg.text = str( + "POS: ", position, "\n", + "ROT: ", rad_to_deg(rotation.y), "\n" + )