basic b3d parsing, X parser patches (needs rewriting!), door creation (broken)

This commit is contained in:
Holly Stubbs 2025-02-16 02:29:02 +00:00
parent aea7107a7b
commit e1e638dfac
Signed by: tgpholly
GPG key ID: B8583C4B7D18119E
13 changed files with 3928 additions and 189 deletions

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=7 format=3 uid="uid://bw0tk6ml7gayq"] [gd_scene load_steps=7 format=3 uid="uid://bc46lc1tdvrio"]
[ext_resource type="Script" path="res://src/DynamicMap.gd" id="1_mytgt"] [ext_resource type="Script" path="res://src/DynamicMap.gd" id="1_mytgt"]
[ext_resource type="Script" path="res://src/TempDebugCamera.gd" id="2_co6fy"] [ext_resource type="Script" path="res://src/TempDebugCamera.gd" id="2_co6fy"]

File diff suppressed because it is too large Load diff

View file

@ -24,7 +24,7 @@ var MISSING_TEXTURE = load("res://missing.png")
func LoadTexture(rawFileName: String): func LoadTexture(rawFileName: String):
var fixedName = rawFileName.replace("\\", "/") var fixedName = rawFileName.replace("\\", "/")
var fileName = Utils.GetCaseiFileName(str("res://", fixedName)) var fileName = Utils.GetCaseiFileName(str("" if rawFileName.contains("res://") else "res://", fixedName))
if fileName == null: if fileName == null:
return MISSING_TEXTURE return MISSING_TEXTURE
elif fileName.contains("<null>"): elif fileName.contains("<null>"):

View file

@ -10,6 +10,7 @@ func _ready() -> void:
) )
$Launch.connect("clicked", func(): $Launch.connect("clicked", func():
get_tree().change_scene_to_file("res://scenes/screens/GameStartup.tscn") get_tree().change_scene_to_file("res://scenes/screens/GameStartup.tscn")
#get_tree().change_scene_to_file("res://scenes/world/DynamicMap.tscn")
) )
$Exit.connect("clicked", func(): $Exit.connect("clicked", func():
get_tree().quit.call_deferred() get_tree().quit.call_deferred()

View file

@ -4,5 +4,9 @@ func _ready() -> void:
loadToLauncher.call_deferred() loadToLauncher.call_deferred()
func loadToLauncher(): func loadToLauncher():
var osName = OS.get_name()
if osName == "Web" or osName == "Android": # TODO: ios, can't be bothered rn
get_tree().change_scene_to_file("res://scenes/screens/IntroVideo.tscn")
else:
get_tree().change_scene_to_file("res://scenes/screens/UpdateChecker.tscn") get_tree().change_scene_to_file("res://scenes/screens/UpdateChecker.tscn")
#get_tree().change_scene_to_file("res://scenes/screens/Launcher.tscn") #get_tree().change_scene_to_file("res://scenes/screens/Launcher.tscn")

View file

@ -143,3 +143,14 @@ static func get_node_aabb(node : Node3D = null, ignore_top_level : bool = true,
box = box.merge(child_box) box = box.merge(child_box)
return box return box
static func StripFilename(file: String):
var mi = ""
var lastSlash = 0
if len(file) > 0:
for i in range(len(file)):
mi = file.substr(i, 1)
if mi == "\\" or mi == "/":
lastSlash = i
return file.substr(0, lastSlash + 1)

View file

@ -2,6 +2,7 @@ class_name B3D
var textures: Array = [] var textures: Array = []
var brushes: Array = [] var brushes: Array = []
var rootPath: String = ""
static func ReadChunk(reader:BufferStuffReader): static func ReadChunk(reader:BufferStuffReader):
var chunk = B3DChunk.new() var chunk = B3DChunk.new()
@ -28,6 +29,7 @@ static func ReadTextures(reader:BufferStuffReader, parsedResult: B3D):
textureChunk.pos = reader.readVector2() textureChunk.pos = reader.readVector2()
textureChunk.scale = reader.readVector2() textureChunk.scale = reader.readVector2()
textureChunk.rotation = reader.readFloat() textureChunk.rotation = reader.readFloat()
textureChunk.tex = Global.LoadTexture(str(parsedResult.rootPath, textureChunk.name))
parsedResult.textures.push_back(textureChunk) parsedResult.textures.push_back(textureChunk)
static func ReadBone(reader:BufferStuffReader): static func ReadBone(reader:BufferStuffReader):
@ -45,32 +47,26 @@ static func ReadVRTS(reader:BufferStuffReader):
vrtsChunk.flags = reader.readInt() vrtsChunk.flags = reader.readInt()
vrtsChunk.tex_coord_sets = reader.readInt() vrtsChunk.tex_coord_sets = reader.readInt()
vrtsChunk.tex_coord_set_size = reader.readInt() vrtsChunk.tex_coord_set_size = reader.readInt()
for i in range(vrtsChunk.tex_coord_set_size):
vrtsChunk.uv.push_back(PackedVector2Array())
while reader.offset < reader.buffer.size(): while reader.offset < reader.buffer.size():
var vertex = reader.readVector3(true) var vertex = reader.readVector3(true)
vrtsChunk.vertices.push_back(vertex) vrtsChunk.vertices.push_back(vertex)
if vrtsChunk.containsNormals: if (vrtsChunk.flags & 1) != 0:
var normal = reader.readVector3(true) var normal = reader.readVector3()
vrtsChunk.normals.push_back(normal) vrtsChunk.normals.push_back(normal)
else:
vrtsChunk.normals.push_back(Vector3.ZERO)
if vrtsChunk.containsColors: if (vrtsChunk.flags & 2) != 0:
var color = reader.readColor() var color = reader.readColor()
vrtsChunk.colors.push_back(color) vrtsChunk.colors.push_back(color)
else:
vrtsChunk.colors.push_back(Color.WHITE)
for i in range(vrtsChunk.tex_coord_set_size):
vrtsChunk.uv.push_back(reader.readVector2())
for i in range(vrtsChunk.tex_coord_sets): for i in range(vrtsChunk.tex_coord_sets):
for i1 in range(vrtsChunk.tex_coord_set_size): var uvData = []
if i == 0: for j in range(vrtsChunk.tex_coord_set_size):
vrtsChunk.uv[i1].x = reader.readFloat() uvData.push_back(reader.readFloat())
else: vrtsChunk.uv[i].push_back(Vector2(uvData[0], uvData[1]));
vrtsChunk.uv[i1].y = reader.readFloat()
return vrtsChunk return vrtsChunk
static func ReadTRIS(reader:BufferStuffReader): static func ReadTRIS(reader:BufferStuffReader):
@ -81,7 +77,6 @@ static func ReadTRIS(reader:BufferStuffReader):
trisChunk.triangles.push_back(reader.readInt()) trisChunk.triangles.push_back(reader.readInt())
trisChunk.triangles.push_back(reader.readInt()) trisChunk.triangles.push_back(reader.readInt())
trisChunk.triangles.push_back(reader.readInt()) trisChunk.triangles.push_back(reader.readInt())
return trisChunk return trisChunk
static func ReadMesh(reader:BufferStuffReader): static func ReadMesh(reader:BufferStuffReader):
@ -98,7 +93,7 @@ static func ReadMesh(reader:BufferStuffReader):
return meshChunk return meshChunk
static func CreateMesh(meshData: B3DMesh): static func CreateMesh(meshData: B3DMesh, parsedResult: B3D):
var arr_mesh = ArrayMesh.new() var arr_mesh = ArrayMesh.new()
var arr = [] var arr = []
arr.resize(Mesh.ARRAY_MAX) arr.resize(Mesh.ARRAY_MAX)
@ -112,25 +107,25 @@ static func CreateMesh(meshData: B3DMesh):
#parentShart.add_child(shit) #parentShart.add_child(shit)
#return parentShart #return parentShart
print(meshData.verts.vertices.size(), ", ", meshData.verts.uv.size(), ", ", meshData.surfaces.triangles.size()) print(meshData.verts.vertices.size(), ", ", meshData.verts.uv[0].size(), ", ", meshData.surfaces.triangles.size())
arr[Mesh.ARRAY_VERTEX]=meshData.verts.vertices arr[Mesh.ARRAY_VERTEX]=meshData.verts.vertices
arr[Mesh.ARRAY_TEX_UV]=meshData.verts.uv arr[Mesh.ARRAY_TEX_UV]=meshData.verts.uv[0]
arr[Mesh.ARRAY_INDEX]=meshData.surfaces.triangles arr[Mesh.ARRAY_INDEX]=meshData.surfaces.triangles
var meshInstance = MeshInstance3D.new() var meshInstance = MeshInstance3D.new()
arr_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr) arr_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr)
meshInstance.mesh = arr_mesh meshInstance.mesh = arr_mesh
var mat = StandardMaterial3D.new() var mat = StandardMaterial3D.new()
mat.albedo_color = Color(randi() % 255 / 255.0, randi() % 255 / 255.0, randi() % 255 / 255.0) #mat.albedo_color = Color(randi() % 255 / 255.0, randi() % 255 / 255.0, randi() % 255 / 255.0)
#mat.albedo_texture = activeAlbedo mat.albedo_texture = parsedResult.textures[0].tex
#mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_DEPTH_PRE_PASS if activeAlbedoHasAlpha else BaseMaterial3D.TRANSPARENCY_DISABLED #mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_DEPTH_PRE_PASS if activeAlbedoHasAlpha else BaseMaterial3D.TRANSPARENCY_DISABLED
meshInstance.set_surface_override_material(0, mat) meshInstance.set_surface_override_material(0, mat)
meshInstance.create_trimesh_collision() meshInstance.create_trimesh_collision()
return meshInstance return meshInstance
static func ReadNode(reader:BufferStuffReader): static func ReadNode(reader:BufferStuffReader, parsedResult: B3D):
var node = B3DNode.new() var node = B3DNode.new()
node.name = reader.readCString() node.name = reader.readCString()
@ -143,12 +138,12 @@ static func ReadNode(reader:BufferStuffReader):
for chunk in chunks: for chunk in chunks:
var chunkReader = BufferStuffReader.create(chunk.bytes) var chunkReader = BufferStuffReader.create(chunk.bytes)
if chunk.name == "NODE": if chunk.name == "NODE":
node.add_child(ReadNode(chunkReader)) node.add_child(ReadNode(chunkReader, parsedResult))
elif chunk.name == "BONE": elif chunk.name == "BONE":
node.bone = ReadBone(chunkReader) node.bone = ReadBone(chunkReader)
elif chunk.name == "MESH": elif chunk.name == "MESH":
node.mesh = ReadMesh(chunkReader) node.mesh = ReadMesh(chunkReader)
node.add_child(CreateMesh(node.mesh)) node.add_child(CreateMesh(node.mesh, parsedResult))
return node return node
@ -157,13 +152,14 @@ static func ReadBrush(reader:BufferStuffReader):
pass pass
static func Load(filePath: String): static func Load(filePath: String):
var correctedPath = filePath.replace("\\", "/") var correctedPath = str("res://", filePath.replace("\\", "/"))
var fileHandle = FileAccess.open(str("res://", correctedPath), FileAccess.READ) var fileHandle = FileAccess.open(correctedPath, FileAccess.READ)
var reader = BufferStuffReader.create(fileHandle.get_buffer(fileHandle.get_length())) var reader = BufferStuffReader.create(fileHandle.get_buffer(fileHandle.get_length()))
fileHandle.close() fileHandle.close()
var parsedResult = B3D.new() var parsedResult = B3D.new()
parsedResult.rootPath = Utils.StripFilename(correctedPath)
var resultScene = Node3D.new() var resultScene = Node3D.new()
var bb3dChunk = ReadChunk(reader) var bb3dChunk = ReadChunk(reader)
@ -180,7 +176,7 @@ static func Load(filePath: String):
elif chunk.name == "BRUS": elif chunk.name == "BRUS":
ReadBrush(chunkReader) ReadBrush(chunkReader)
elif chunk.name == "NODE": elif chunk.name == "NODE":
resultScene.add_child(ReadNode(chunkReader)) resultScene.add_child(ReadNode(chunkReader, parsedResult))
print(resultScene) print(resultScene)
return resultScene return resultScene

View file

@ -4,17 +4,6 @@ static func ReadString(reader:BufferStuffReader):
var length = reader.readInt() var length = reader.readInt()
return reader.readBuffer(length).get_string_from_ascii() return reader.readBuffer(length).get_string_from_ascii()
static func StripFilename(file: String):
var mi = ""
var lastSlash = 0
if len(file) > 0:
for i in range(len(file)):
mi = file.substr(i, 1)
if mi == "\\" or mi == "/":
lastSlash = i
return file.substr(0, lastSlash + 1)
static var EMPTY_TEXTURE = Texture2D.new() static var EMPTY_TEXTURE = Texture2D.new()
static var RMESH_LOAD_COUNT = 0 static var RMESH_LOAD_COUNT = 0
@ -51,7 +40,7 @@ static func LoadRMesh(file: String, rt: RoomTemplate):
var count: int = 0 var count: int = 0
var count2: int = 0 var count2: int = 0
file = StripFilename(file) file = Utils.StripFilename(file)
#print(file) #print(file)
var i var i
@ -478,7 +467,7 @@ static func LoadRMesh(file: String, rt: RoomTemplate):
temp1i=0 temp1i=0
for j1 in range(Constants.MaxRoomEmitters - 1): for j1 in range(Constants.MaxRoomEmitters - 1):
if rt.TempSoundEmitter[j1] == null: if rt.TempSoundEmitter[j1] == null:
rt.TempSoundEmitterX[j1] = reader.readFloat() * Constants.RoomScale rt.TempSoundEmitterX[j1] = -reader.readFloat() * Constants.RoomScale
rt.TempSoundEmitterY[j1] = reader.readFloat() * Constants.RoomScale rt.TempSoundEmitterY[j1] = reader.readFloat() * Constants.RoomScale
rt.TempSoundEmitterZ[j1] = reader.readFloat() * Constants.RoomScale rt.TempSoundEmitterZ[j1] = reader.readFloat() * Constants.RoomScale
rt.TempSoundEmitter[j1] = reader.readInt() rt.TempSoundEmitter[j1] = reader.readInt()

View file

@ -1,5 +1,39 @@
class_name X class_name X
# ending it right now, oh my god this is awful.
# https://learn.microsoft.com/en-us/windows/win32/direct3d9/dx9-graphics-reference-x-file-interfaces
static func _CalcMinMaxPos(verts: PackedVector3Array) -> 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 vert in verts:
if vert.x < minX:
minX = vert.x
if vert.x > maxX:
maxX = vert.x
if vert.y < minY:
minY = vert.y
if vert.y > maxY:
maxY = vert.y
if vert.z < minZ:
minZ = vert.z
if vert.z > maxZ:
maxZ = vert.z
return Vector3(abs(minX - maxX), abs(minY - maxY), abs(minZ - maxZ))
static func MeshWidth(mesh: Node) -> float:
return mesh.get_meta("meshWidth")
static func MeshHeight(mesh: Node) -> float:
return mesh.get_meta("meshHeight")
static func MeshDepth(mesh: Node) -> float:
return mesh.get_meta("meshDepth")
static func LoadModel(filePath: String): static func LoadModel(filePath: String):
var sillyPath = str("res://", filePath.replace("/Map/", "/map/")) var sillyPath = str("res://", filePath.replace("/Map/", "/map/"))
var file = FileAccess.open(sillyPath, FileAccess.READ) var file = FileAccess.open(sillyPath, FileAccess.READ)
@ -11,9 +45,12 @@ static func LoadModel(filePath: String):
var fileLines = file.get_as_text(true).split("\n") var fileLines = file.get_as_text(true).split("\n")
var meshDataStart = false var meshDataStart = false
var hitMeshOnce = false
var indexDataStart = false var indexDataStart = false
var meshTextureCoordsStart = false var meshTextureCoordsStart = false
var hitTexCoordsOnce = false
var textureNameStart = false var textureNameStart = false
var hitTextureOnce = false
var textureName = "" var textureName = ""
var texture: Texture2D = null var texture: Texture2D = null
var meshDataLength = -1 var meshDataLength = -1
@ -22,7 +59,16 @@ static func LoadModel(filePath: String):
var verts = PackedVector3Array() var verts = PackedVector3Array()
var uvs = PackedVector2Array() var uvs = PackedVector2Array()
var indexes = PackedInt32Array() var indexes = PackedInt32Array()
# oh god oh fuck i hope not
var is3dWorldStudioFile = false
for line in fileLines: for line in fileLines:
if line.contains("3D World Studio"):
is3dWorldStudioFile = true
var stripLine = line.strip_edges().strip_escapes().replace(" ", "")
if stripLine == "{" or stripLine == "}":
continue
if meshDataStart or indexDataStart: if meshDataStart or indexDataStart:
if meshDataStart and meshDataLength == -1: if meshDataStart and meshDataLength == -1:
meshDataLength = int(line.strip_edges().split(";")[0]) meshDataLength = int(line.strip_edges().split(";")[0])
@ -53,17 +99,31 @@ static func LoadModel(filePath: String):
if uvsDataLength == -1: if uvsDataLength == -1:
uvsDataLength = int(line.strip_edges().split(";")[0]) uvsDataLength = int(line.strip_edges().split(";")[0])
else: else:
var uvParts = line.strip_edges().split(";") # NOTE: THE FORMAT IS DIFFERENT ON FILES MADE IN
# 3D WORLD STUDIO FOR SOME REASON?!
if is3dWorldStudioFile:
var uvParts = line.strip_edges().strip_escapes().split(";")
if uvParts.size() == 3:
meshTextureCoordsStart = false
else:
var uvShit = uvParts[0].split(",")
uvs.push_back(Vector2(float(uvShit[0]), float(uvShit[1])))
else:
var uvParts = line.strip_edges().strip_escapes().split(";")
if uvParts.size() == 4: if uvParts.size() == 4:
meshTextureCoordsStart = false meshTextureCoordsStart = false
else:
uvs.push_back(Vector2(float(uvParts[0]), float(uvParts[1]))) uvs.push_back(Vector2(float(uvParts[0]), float(uvParts[1])))
if line.strip_edges().contains("Mesh "): if line.strip_edges().contains("Mesh ") and not hitMeshOnce:
meshDataStart = true meshDataStart = true
elif line.strip_edges().contains("TextureFilename"): hitMeshOnce = true
elif line.strip_edges().contains("TextureFilename") and not hitTextureOnce:
textureNameStart = true textureNameStart = true
elif line.strip_edges().contains("MeshTextureCoords"): hitTextureOnce = true
elif line.strip_edges().contains("MeshTextureCoords") and not hitTexCoordsOnce:
meshTextureCoordsStart = true meshTextureCoordsStart = true
hitTexCoordsOnce = true
var mesh = MeshInstance3D.new() var mesh = MeshInstance3D.new()
var arr_mesh = ArrayMesh.new() var arr_mesh = ArrayMesh.new()
@ -84,4 +144,8 @@ static func LoadModel(filePath: String):
meshInstance.set_surface_override_material(0, mat) meshInstance.set_surface_override_material(0, mat)
meshInstance.create_trimesh_collision() meshInstance.create_trimesh_collision()
meshInstance.name = str(filePath, "_", Time.get_unix_time_from_system()) meshInstance.name = str(filePath, "_", Time.get_unix_time_from_system())
var meshSize = _CalcMinMaxPos(verts)
meshInstance.set_meta("meshWidth", meshSize.x)
meshInstance.set_meta("meshHeight", meshSize.y)
meshInstance.set_meta("meshDepth", meshSize.z)
return meshInstance return meshInstance

View file

@ -6,3 +6,4 @@ var blend: int = 0
var pos: Vector2 var pos: Vector2
var scale: Vector2 var scale: Vector2
var rotation: float = 0.0 var rotation: float = 0.0
var tex: Texture2D

View file

@ -1,19 +1,10 @@
class_name B3DVertices class_name B3DVertices
var flags: int: set = _flagsUpdated var flags: int
var tex_coord_sets: int = 1 var tex_coord_sets: int = 1
var tex_coord_set_size: int = 0 var tex_coord_set_size: int = 0
var containsNormals: bool = false
var containsColors: bool = false
func _flagsUpdated(flagValue: int):
flags = flagValue
containsNormals = (flags & 1) != 0
containsColors = (flags & 2) != 0
var vertices: PackedVector3Array = PackedVector3Array() var vertices: PackedVector3Array = PackedVector3Array()
var normals: PackedVector3Array = PackedVector3Array() var normals: PackedVector3Array = PackedVector3Array()
var colors: PackedColorArray = PackedColorArray() var colors: PackedColorArray = PackedColorArray()
var uv: PackedVector2Array = PackedVector2Array() var uv: Array = []

40
src/objects/Door.gd Normal file
View file

@ -0,0 +1,40 @@
class_name Door
var obj: Node3D
var obj2: Node3D
var frameobj: Node
var buttons = Utils.Init1DArray(2) # %[2]
var locked: bool
var open: bool
var angle: float
var openstate: int
var fastopen: float
var dir: float
var timer: float
var timerstate: float
var KeyCard: int
var room: Room
var DisableWaypoint: bool
var dist: float
#var SoundCHN
var Code: String
var ID: int
var Level: int
var LevelDest: int
var AutoClose: bool
var LinkedDoor: Door
var IsElevatorDoor: bool = false
var MTFClose: bool = true
var NPCCalledElevator: bool = false
var DoorHitOBJ: Node3D

View file

@ -1,5 +1,11 @@
class_name Room class_name Room
static var G_ROOM_ID = 0
static func _GetRoomID():
G_ROOM_ID += 1
return G_ROOM_ID
var ID = _GetRoomID()
var zone: int var zone: int
var found var found