X model nonsense
This commit is contained in:
parent
e1e638dfac
commit
980dc66f94
15 changed files with 599 additions and 107 deletions
|
@ -5,14 +5,16 @@ func _ready() -> void:
|
||||||
#B3D.Load("GFX\\npcs\\106_2.b3d")
|
#B3D.Load("GFX\\npcs\\106_2.b3d")
|
||||||
#add_child(B3D.Load("GFX\\apache.b3d"))
|
#add_child(B3D.Load("GFX\\apache.b3d"))
|
||||||
|
|
||||||
|
X.LoadModel("res://GFX/map/Door01.x")
|
||||||
|
|
||||||
#DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
|
#DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
|
||||||
|
|
||||||
#RMesh.LoadRMesh(self, roomInfo["mesh path"])
|
#RMesh.LoadRMesh(self, roomInfo["mesh path"])
|
||||||
|
|
||||||
#CreateMap()
|
#CreateMap()
|
||||||
IntroEnabled = true
|
IntroEnabled = true
|
||||||
LoadRoomTemplates("Data/rooms.ini")
|
#LoadRoomTemplates("Data/rooms.ini")
|
||||||
CreateMap()
|
#CreateMap()
|
||||||
|
|
||||||
var IntroEnabled: bool
|
var IntroEnabled: bool
|
||||||
var I_Zone: MapZones = MapZones.new()
|
var I_Zone: MapZones = MapZones.new()
|
||||||
|
@ -52,7 +54,9 @@ func CreateDoor(lvl, x:float, y:float, z:float, angle:float, room:Room, dopen =
|
||||||
var d2:Door
|
var d2:Door
|
||||||
|
|
||||||
var d = Door.new()
|
var d = Door.new()
|
||||||
|
doors.push_back(d)
|
||||||
if big == 1:
|
if big == 1:
|
||||||
|
print("DOORS: Creating ContDoor in " + room.RoomTemplate.Name, ", X: ", x, ", Y: ", y, " Z: ", z)
|
||||||
d.obj = X.LoadModel("GFX/map/ContDoorLeft.x")#CopyEntity(BigDoorOBJ(0))
|
d.obj = X.LoadModel("GFX/map/ContDoorLeft.x")#CopyEntity(BigDoorOBJ(0))
|
||||||
d.obj.scale.x = 55 * Constants.RoomScale
|
d.obj.scale.x = 55 * Constants.RoomScale
|
||||||
d.obj.scale.y = 55 * Constants.RoomScale
|
d.obj.scale.y = 55 * Constants.RoomScale
|
||||||
|
@ -69,6 +73,7 @@ func CreateDoor(lvl, x:float, y:float, z:float, angle:float, room:Room, dopen =
|
||||||
#EntityType d\frameobj, HIT_MAP
|
#EntityType d\frameobj, HIT_MAP
|
||||||
#EntityAlpha d\frameobj, 0.0
|
#EntityAlpha d\frameobj, 0.0
|
||||||
elif big == 2:
|
elif big == 2:
|
||||||
|
print("DOORS: Creating HeavyDoor in " + room.RoomTemplate.Name, ", X: ", x, ", Y: ", y, " Z: ", z)
|
||||||
d.obj = X.LoadModel("GFX/map/heavydoor1.x")#CopyEntity(HeavyDoorObj(0))
|
d.obj = X.LoadModel("GFX/map/heavydoor1.x")#CopyEntity(HeavyDoorObj(0))
|
||||||
d.obj.scale.x = Constants.RoomScale
|
d.obj.scale.x = Constants.RoomScale
|
||||||
d.obj.scale.y = Constants.RoomScale
|
d.obj.scale.y = Constants.RoomScale
|
||||||
|
@ -80,6 +85,7 @@ func CreateDoor(lvl, x:float, y:float, z:float, angle:float, room:Room, dopen =
|
||||||
|
|
||||||
d.frameobj = X.LoadModel("GFX/map/doorframe.x")#CopyEntity(DoorFrameOBJ)
|
d.frameobj = X.LoadModel("GFX/map/doorframe.x")#CopyEntity(DoorFrameOBJ)
|
||||||
elif big == 3:
|
elif big == 3:
|
||||||
|
print("DOORS: Creating ElevatorDoor in " + room.RoomTemplate.Name, ", X: ", x, ", Y: ", y, " Z: ", z)
|
||||||
print("TODO: ELEVATOR DOOR!")
|
print("TODO: ELEVATOR DOOR!")
|
||||||
#for d2 = Each Doors
|
#for d2 = Each Doors
|
||||||
#If d2 <> d And d2\dir = 3 Then
|
#If d2 <> d And d2\dir = 3 Then
|
||||||
|
@ -98,6 +104,7 @@ func CreateDoor(lvl, x:float, y:float, z:float, angle:float, room:Room, dopen =
|
||||||
#EndIf
|
#EndIf
|
||||||
#d\frameobj = CopyEntity(DoorFrameOBJ)
|
#d\frameobj = CopyEntity(DoorFrameOBJ)
|
||||||
else:
|
else:
|
||||||
|
print("DOORS: Creating Door in " + room.RoomTemplate.Name, ", X: ", x, ", Y: ", y, " Z: ", z)
|
||||||
d.obj = X.LoadModel("GFX/map/door01.x")#CopyEntity(DoorOBJ)
|
d.obj = X.LoadModel("GFX/map/door01.x")#CopyEntity(DoorOBJ)
|
||||||
d.obj.scale.x = (204.0 * Constants.RoomScale) / X.MeshWidth(d.obj)
|
d.obj.scale.x = (204.0 * Constants.RoomScale) / X.MeshWidth(d.obj)
|
||||||
d.obj.scale.y = 312.0 * Constants.RoomScale / X.MeshHeight(d.obj)
|
d.obj.scale.y = 312.0 * Constants.RoomScale / X.MeshHeight(d.obj)
|
||||||
|
@ -166,8 +173,6 @@ func CreateDoor(lvl, x:float, y:float, z:float, angle:float, room:Room, dopen =
|
||||||
d.buttons[1].position.z = z + 0.1
|
d.buttons[1].position.z = z + 0.1
|
||||||
d.buttons[1].rotation.y = 180
|
d.buttons[1].rotation.y = 180
|
||||||
|
|
||||||
d.frameobj.add_child(d.buttons[0])
|
|
||||||
d.frameobj.add_child(d.buttons[1])
|
|
||||||
#EntityPickMode(d\buttons[0], 2)
|
#EntityPickMode(d\buttons[0], 2)
|
||||||
#EntityPickMode(d\buttons[1], 2)
|
#EntityPickMode(d\buttons[1], 2)
|
||||||
|
|
||||||
|
@ -232,7 +237,7 @@ func CreateDoor(lvl, x:float, y:float, z:float, angle:float, room:Room, dopen =
|
||||||
#EntityType d\DoorHitOBJ,HIT_MAP
|
#EntityType d\DoorHitOBJ,HIT_MAP
|
||||||
#EntityColor d\DoorHitOBJ,255,0,0
|
#EntityColor d\DoorHitOBJ,255,0,0
|
||||||
#HideEntity d\DoorHitOBJ
|
#HideEntity d\DoorHitOBJ
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
func FillRoom(r:Room):
|
func FillRoom(r:Room):
|
||||||
|
|
|
@ -1,7 +1,24 @@
|
||||||
class_name X
|
class_name X
|
||||||
|
|
||||||
# ending it right now, oh my god this is awful.
|
# this is awful. i hate microsoft so much.
|
||||||
# https://learn.microsoft.com/en-us/windows/win32/direct3d9/dx9-graphics-reference-x-file-interfaces
|
# 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
|
||||||
|
|
||||||
|
var majorVersion = 0
|
||||||
|
var minorVersion = 0
|
||||||
|
var isBinaryFormat = false
|
||||||
|
var lineNumber = 0
|
||||||
|
var binaryFloatSize = 0
|
||||||
|
var binaryNumCount = 0
|
||||||
|
var p = -1
|
||||||
|
var end = -1
|
||||||
|
var compressed = false
|
||||||
|
var file: PackedByteArray
|
||||||
|
var scene = Node3D.new()
|
||||||
|
var meshes: Array
|
||||||
|
var materials: Array
|
||||||
|
|
||||||
|
const MAX_TEX_COORDS = 2
|
||||||
|
|
||||||
static func _CalcMinMaxPos(verts: PackedVector3Array) -> Vector3:
|
static func _CalcMinMaxPos(verts: PackedVector3Array) -> Vector3:
|
||||||
var minX: float = 0
|
var minX: float = 0
|
||||||
|
@ -34,118 +51,578 @@ static func MeshHeight(mesh: Node) -> float:
|
||||||
static func MeshDepth(mesh: Node) -> float:
|
static func MeshDepth(mesh: Node) -> float:
|
||||||
return mesh.get_meta("meshDepth")
|
return mesh.get_meta("meshDepth")
|
||||||
|
|
||||||
|
func GetStringBytes(start: int, end: int):
|
||||||
|
return file.slice(start, end).get_string_from_ascii()
|
||||||
|
|
||||||
|
func ReadUntilEndOfLine():
|
||||||
|
if isBinaryFormat:
|
||||||
|
return
|
||||||
|
while p > end:
|
||||||
|
var tmp = GetStringBytes(p, p + 1)
|
||||||
|
if tmp == "\n":
|
||||||
|
p += 1
|
||||||
|
lineNumber += 1
|
||||||
|
return
|
||||||
|
p += 1
|
||||||
|
|
||||||
|
func FindNextNonWhiteSpace():
|
||||||
|
if isBinaryFormat:
|
||||||
|
return
|
||||||
|
|
||||||
|
while true:
|
||||||
|
while p < end and (GetStringBytes(p, p + 1) == " " or GetStringBytes(p, p + 1) == "\r" or GetStringBytes(p, p + 1) == "\n"):
|
||||||
|
if GetStringBytes(p, p + 1) == "\n":
|
||||||
|
lineNumber += 1
|
||||||
|
p += 1
|
||||||
|
if p >= end:
|
||||||
|
return
|
||||||
|
# is comment?
|
||||||
|
if GetStringBytes(p, p + 2) == "//" or GetStringBytes(p, p + 1) == "#":
|
||||||
|
ReadUntilEndOfLine()
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
static func LoadModel(filePath: String):
|
static func LoadModel(filePath: String):
|
||||||
var sillyPath = str("res://", filePath.replace("/Map/", "/map/"))
|
var sillyPath = str("" if filePath.contains("res://") else "res://", filePath.replace("/Map/", "/map/"))
|
||||||
var file = FileAccess.open(sillyPath, FileAccess.READ)
|
var file = FileAccess.open(sillyPath, FileAccess.READ)
|
||||||
|
|
||||||
# Do a case insensitive lookup only if we have to, it's more expensive.
|
# Do a case insensitive lookup only if we have to, it's more expensive.
|
||||||
if file == null:
|
if file == null:
|
||||||
file = FileAccess.open(Utils.GetCaseiFileName(sillyPath), FileAccess.READ)
|
file = FileAccess.open(Utils.GetCaseiFileName(sillyPath), FileAccess.READ)
|
||||||
|
|
||||||
var fileLines = file.get_as_text(true).split("\n")
|
var x = X.new()
|
||||||
|
|
||||||
var meshDataStart = false
|
x.majorVersion = 0
|
||||||
var hitMeshOnce = false
|
x.minorVersion = 0
|
||||||
var indexDataStart = false
|
x.isBinaryFormat = false
|
||||||
var meshTextureCoordsStart = false
|
x.binaryFloatSize = 0
|
||||||
var hitTexCoordsOnce = false
|
x.binaryNumCount = 0
|
||||||
var textureNameStart = false
|
x.p = 0
|
||||||
var hitTextureOnce = false
|
x.end = file.get_length()
|
||||||
var textureName = ""
|
|
||||||
var texture: Texture2D = null
|
x.file = file.get_buffer(x.end)
|
||||||
var meshDataLength = -1
|
file.close()
|
||||||
var uvsDataLength = -1
|
|
||||||
var indexDataLength = -1
|
if x.GetStringBytes(x.p, x.p + 4) != "xof ":
|
||||||
var verts = PackedVector3Array()
|
assert(false, "This is not a DirectX file!")
|
||||||
var uvs = PackedVector2Array()
|
return
|
||||||
var indexes = PackedInt32Array()
|
|
||||||
# oh god oh fuck i hope not
|
x.majorVersion = int(x.GetStringBytes(4, 6))
|
||||||
var is3dWorldStudioFile = false
|
x.minorVersion = int(x.GetStringBytes(6, 8))
|
||||||
for line in fileLines:
|
|
||||||
if line.contains("3D World Studio"):
|
x.compressed = false
|
||||||
is3dWorldStudioFile = true
|
var fileTypeRaw = x.GetStringBytes(8, 12)
|
||||||
|
if fileTypeRaw == "txt ":
|
||||||
|
x.isBinaryFormat = false
|
||||||
|
elif fileTypeRaw == "bin ":
|
||||||
|
x.isBinaryFormat = true
|
||||||
|
elif fileTypeRaw == "tzip":
|
||||||
|
x.isBinaryFormat = false
|
||||||
|
x.compressed = true
|
||||||
|
elif fileTypeRaw == "bzip":
|
||||||
|
x.isBinaryFormat = true
|
||||||
|
x.compressed = true
|
||||||
|
else:
|
||||||
|
assert(false, str("Unsupported DirectX file format: ", fileTypeRaw))
|
||||||
|
|
||||||
var stripLine = line.strip_edges().strip_escapes().replace(" ", "")
|
if x.isBinaryFormat or x.compressed:
|
||||||
if stripLine == "{" or stripLine == "}":
|
assert(false, "Binary and Compressed files are currently unsupported!")
|
||||||
continue
|
return
|
||||||
|
|
||||||
if meshDataStart or indexDataStart:
|
x.binaryFloatSize = int(x.GetStringBytes(12, 16))
|
||||||
if meshDataStart and meshDataLength == -1:
|
|
||||||
meshDataLength = int(line.strip_edges().split(";")[0])
|
if x.binaryFloatSize != 32 and x.binaryFloatSize != 64:
|
||||||
elif indexDataStart and indexDataLength == -1:
|
assert(false, str("Unknown float size ", x.binaryFloatSize, " specified in DirectX file header."))
|
||||||
indexDataLength = int(line.strip_edges().split(";")[0])
|
|
||||||
elif meshDataStart:
|
|
||||||
var pointData = line.strip_edges().split(";")
|
|
||||||
if pointData.size() == 5:
|
|
||||||
meshDataStart = false
|
|
||||||
indexDataStart = true
|
|
||||||
verts.push_back(Vector3(-float(pointData[0]), float(pointData[1]), float(pointData[2])))
|
|
||||||
elif indexDataStart:
|
|
||||||
var indexParts = line.strip_edges().split(";")
|
|
||||||
if indexParts.size() == 4:
|
|
||||||
indexDataStart = false
|
|
||||||
var indexData = indexParts[1].split(",")
|
|
||||||
var amount = int(indexParts[0])
|
|
||||||
for i in range(amount):
|
|
||||||
indexes.push_back(int(indexData[i]))
|
|
||||||
elif textureNameStart:
|
|
||||||
textureName = line.strip_edges().split(";")[0].replace("\"", "")
|
|
||||||
var texturePath = str("GFX/map/Props/", textureName)
|
|
||||||
texture = Global.GetTextureFromCache(texturePath)
|
|
||||||
if not texture:
|
|
||||||
texture = Global.LoadTexture(texturePath)
|
|
||||||
textureNameStart = false
|
|
||||||
elif meshTextureCoordsStart:
|
|
||||||
if uvsDataLength == -1:
|
|
||||||
uvsDataLength = int(line.strip_edges().split(";")[0])
|
|
||||||
else:
|
|
||||||
# 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:
|
|
||||||
meshTextureCoordsStart = false
|
|
||||||
else:
|
|
||||||
uvs.push_back(Vector2(float(uvParts[0]), float(uvParts[1])))
|
|
||||||
|
|
||||||
if line.strip_edges().contains("Mesh ") and not hitMeshOnce:
|
x.p += 16
|
||||||
meshDataStart = true
|
|
||||||
hitMeshOnce = true
|
if x.compressed:
|
||||||
elif line.strip_edges().contains("TextureFilename") and not hitTextureOnce:
|
# hard pass
|
||||||
textureNameStart = true
|
pass
|
||||||
hitTextureOnce = true
|
else:
|
||||||
elif line.strip_edges().contains("MeshTextureCoords") and not hitTexCoordsOnce:
|
x.ReadUntilEndOfLine()
|
||||||
meshTextureCoordsStart = true
|
|
||||||
hitTexCoordsOnce = true
|
x.ParseFile()
|
||||||
|
return x.scene
|
||||||
|
|
||||||
|
func ReadBinWord() -> int:
|
||||||
|
assert(end - p >= 2)
|
||||||
|
var tmp = file.decode_u16(p)
|
||||||
|
p += 2
|
||||||
|
return tmp
|
||||||
|
|
||||||
|
func GetNextToken():
|
||||||
|
var s: String = ""
|
||||||
|
if isBinaryFormat:
|
||||||
|
# I am NOT doing this right now
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
FindNextNonWhiteSpace()
|
||||||
|
if p >= end:
|
||||||
|
return s
|
||||||
|
|
||||||
var mesh = MeshInstance3D.new()
|
while p < end and GetStringBytes(p, p + 1) != " ":
|
||||||
var arr_mesh = ArrayMesh.new()
|
var tmp = GetStringBytes(p, p + 1)
|
||||||
var arr = []
|
if tmp == ";" or tmp == "}" or tmp == "{" or tmp == ",":
|
||||||
arr.resize(Mesh.ARRAY_MAX)
|
if not s:
|
||||||
|
s += tmp
|
||||||
|
p += 1
|
||||||
|
break
|
||||||
|
s += GetStringBytes(p, p + 1)
|
||||||
|
p += 1
|
||||||
|
return s
|
||||||
|
|
||||||
|
func ReadHead():
|
||||||
|
var nameOrBrace = GetNextToken()
|
||||||
|
if nameOrBrace != "{":
|
||||||
|
if GetNextToken() != "{":
|
||||||
|
assert(false, "Opening brace expected.")
|
||||||
|
return
|
||||||
|
return nameOrBrace
|
||||||
|
return ""
|
||||||
|
|
||||||
|
# We don't really care about the templates, just skip through them.
|
||||||
|
func ParseTemplate():
|
||||||
|
var name = ReadHead()
|
||||||
|
var guid = GetNextToken()
|
||||||
|
print(name)
|
||||||
|
print(guid)
|
||||||
|
while true:
|
||||||
|
var s = GetNextToken()
|
||||||
|
if s == "}":
|
||||||
|
break
|
||||||
|
if s == null:
|
||||||
|
assert(false, "Unexpected end of file reached while parsing template definition")
|
||||||
|
|
||||||
|
var notSplitChar = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '.', '-', 'e', 'E']
|
||||||
|
|
||||||
|
func CheckForSeparator():
|
||||||
|
if self.isBinaryFormat:
|
||||||
|
return
|
||||||
|
var token = GetNextToken()
|
||||||
|
assert(token == "," or token == ";", "Separator character (';' or ',') expected.")
|
||||||
|
|
||||||
|
func CheckForClosingBrace():
|
||||||
|
if isBinaryFormat:
|
||||||
|
return
|
||||||
|
|
||||||
|
assert(GetNextToken() == "}", "Closing brace expected.")
|
||||||
|
|
||||||
|
func CheckForSemicolon():
|
||||||
|
if isBinaryFormat:
|
||||||
|
return
|
||||||
|
|
||||||
arr[Mesh.ARRAY_VERTEX]=verts
|
assert(GetNextToken() == ";", "Semicolon expected.")
|
||||||
arr[Mesh.ARRAY_TEX_UV]=uvs
|
|
||||||
arr[Mesh.ARRAY_INDEX]=indexes
|
func ReadFloat():
|
||||||
|
if isBinaryFormat:
|
||||||
|
assert(false, "Binary models are currently unsupported.")
|
||||||
|
else:
|
||||||
|
FindNextNonWhiteSpace()
|
||||||
|
|
||||||
|
if GetStringBytes(p, p + 9) == "-1.#IND00" or GetStringBytes(p, p + 8) == "1.#IND00":
|
||||||
|
p += 9
|
||||||
|
CheckForSeparator()
|
||||||
|
return 0.0
|
||||||
|
elif GetStringBytes(p, p + 8) == "1.#QNAN0":
|
||||||
|
p += 8
|
||||||
|
CheckForSeparator()
|
||||||
|
return 0.0
|
||||||
|
var result_ = 0.0
|
||||||
|
var digitStart = p
|
||||||
|
var digitEnd = p
|
||||||
|
while p < end:
|
||||||
|
var c = GetStringBytes(p, p + 1)
|
||||||
|
if c in notSplitChar:
|
||||||
|
digitEnd = p
|
||||||
|
p += 1
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
var tmp = GetStringBytes(digitStart, digitEnd)
|
||||||
|
result_ = float(tmp)
|
||||||
|
CheckForSeparator()
|
||||||
|
return result_
|
||||||
|
|
||||||
|
var digitTable = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
|
||||||
|
|
||||||
|
func ReadInt():
|
||||||
|
if isBinaryFormat:
|
||||||
|
assert(false, "Binary models are currently unsupported.")
|
||||||
|
else:
|
||||||
|
FindNextNonWhiteSpace()
|
||||||
|
var isNegative = false
|
||||||
|
if GetStringBytes(p, p + 1) == "-":
|
||||||
|
isNegative = true
|
||||||
|
p += 1
|
||||||
|
|
||||||
|
var number = 0
|
||||||
|
while p < end:
|
||||||
|
if not (GetStringBytes(p, p + 1) in digitTable):
|
||||||
|
break
|
||||||
|
number = number * 10 + int(GetStringBytes(p, p + 1))
|
||||||
|
p += 1
|
||||||
|
|
||||||
|
CheckForSeparator()
|
||||||
|
if isNegative:
|
||||||
|
return -number
|
||||||
|
else:
|
||||||
|
return number
|
||||||
|
|
||||||
|
func TestForSeparator():
|
||||||
|
if isBinaryFormat:
|
||||||
|
return
|
||||||
|
FindNextNonWhiteSpace()
|
||||||
|
if p >= end:
|
||||||
|
return
|
||||||
|
if GetStringBytes(p, p + 1) == ";" or GetStringBytes(p, p + 1) == ",":
|
||||||
|
p += 1
|
||||||
|
|
||||||
|
func ReadVector2() -> Vector2:
|
||||||
|
var x = ReadFloat()
|
||||||
|
var y = ReadFloat()
|
||||||
|
TestForSeparator()
|
||||||
|
return Vector2(x, y)
|
||||||
|
|
||||||
|
func ReadVector3() -> Vector3:
|
||||||
|
var x = ReadFloat()
|
||||||
|
var y = ReadFloat()
|
||||||
|
var z = ReadFloat()
|
||||||
|
TestForSeparator()
|
||||||
|
return Vector3(x, y, z)
|
||||||
|
|
||||||
|
func ParseTransformationMatrix():
|
||||||
|
ReadHead()
|
||||||
|
|
||||||
var meshInstance = MeshInstance3D.new()
|
var M11 = ReadFloat()
|
||||||
arr_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr)
|
var M21 = ReadFloat()
|
||||||
meshInstance.mesh = arr_mesh
|
var M31 = ReadFloat()
|
||||||
var mat = StandardMaterial3D.new()
|
var M41 = ReadFloat()
|
||||||
#mat.albedo_color = Color(randi() % 255 / 255.0, randi() % 255 / 255.0, randi() % 255 / 255.0)
|
var M12 = ReadFloat()
|
||||||
mat.albedo_texture = texture
|
var M22 = ReadFloat()
|
||||||
#mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_DEPTH_PRE_PASS if activeAlbedoHasAlpha else BaseMaterial3D.TRANSPARENCY_DISABLED
|
var M32 = ReadFloat()
|
||||||
meshInstance.set_surface_override_material(0, mat)
|
var M42 = ReadFloat()
|
||||||
meshInstance.create_trimesh_collision()
|
var M13 = ReadFloat()
|
||||||
meshInstance.name = str(filePath, "_", Time.get_unix_time_from_system())
|
var M23 = ReadFloat()
|
||||||
var meshSize = _CalcMinMaxPos(verts)
|
var M33 = ReadFloat()
|
||||||
meshInstance.set_meta("meshWidth", meshSize.x)
|
var M43 = ReadFloat()
|
||||||
meshInstance.set_meta("meshHeight", meshSize.y)
|
var M14 = ReadFloat()
|
||||||
meshInstance.set_meta("meshDepth", meshSize.z)
|
var M24 = ReadFloat()
|
||||||
return meshInstance
|
var M34 = ReadFloat()
|
||||||
|
var M44 = ReadFloat()
|
||||||
|
|
||||||
|
CheckForSemicolon()
|
||||||
|
CheckForClosingBrace()
|
||||||
|
|
||||||
|
return [M11, M21, M31, M41, M12, M22, M32, M42, M13, M23, M33, M43, M14, M24, M34, M44]
|
||||||
|
|
||||||
|
func ParseMesh(parent: Node):
|
||||||
|
var mesh = XMesh.new()
|
||||||
|
mesh.parent = parent
|
||||||
|
meshes.push_back(mesh)
|
||||||
|
ReadHead()
|
||||||
|
|
||||||
|
var vertCount = ReadInt()
|
||||||
|
for i in range(vertCount):
|
||||||
|
mesh.verts.push_back(ReadVector3())
|
||||||
|
|
||||||
|
var faceCount = ReadInt()
|
||||||
|
for i in range(faceCount):
|
||||||
|
var numIndices = ReadInt()
|
||||||
|
if numIndices < 3:
|
||||||
|
assert(false, str("Invalid index count ", numIndices, " for face ", i))
|
||||||
|
|
||||||
|
for i1 in range(numIndices):
|
||||||
|
mesh.indices.push_back(ReadInt())
|
||||||
|
TestForSeparator()
|
||||||
|
|
||||||
|
while true:
|
||||||
|
var objectName = GetNextToken()
|
||||||
|
print(str("\"",objectName,"\""))
|
||||||
|
if not objectName:
|
||||||
|
assert(false, "Unexpected end of file while parsing mesh structure")
|
||||||
|
elif objectName == "}":
|
||||||
|
break
|
||||||
|
elif objectName == "MeshNormals":
|
||||||
|
ParseMeshNormals(mesh)
|
||||||
|
elif objectName == "MeshTextureCoords":
|
||||||
|
ParseMeshTextureCoords(mesh)
|
||||||
|
elif objectName == "MeshVertexColors":
|
||||||
|
#ParseMeshVertexColors(mesh)
|
||||||
|
ParseUnknownDataObject()
|
||||||
|
elif objectName == "MeshMaterialList":
|
||||||
|
ParseUnknownDataObject()
|
||||||
|
elif objectName == "VertexDuplicationIndices":
|
||||||
|
ParseUnknownDataObject()
|
||||||
|
elif objectName == "XSkinMeshHeader":
|
||||||
|
ParseUnknownDataObject()
|
||||||
|
elif objectName == "SkinWeights":
|
||||||
|
ParseUnknownDataObject()
|
||||||
|
else:
|
||||||
|
print("Unknown data object in mesh in x file")
|
||||||
|
ParseUnknownDataObject()
|
||||||
|
|
||||||
|
return mesh
|
||||||
|
|
||||||
|
func ParseUnknownDataObject():
|
||||||
|
while true:
|
||||||
|
var t = GetNextToken()
|
||||||
|
if len(t) == 0:
|
||||||
|
assert(false, "Unexpected end of file while parsing unknown segment.")
|
||||||
|
|
||||||
|
if t == "{":
|
||||||
|
break
|
||||||
|
|
||||||
|
var counter = 1
|
||||||
|
while counter > 0:
|
||||||
|
var t = GetNextToken()
|
||||||
|
|
||||||
|
if len(t) == 0:
|
||||||
|
assert(false, "Unexpected end of file while parsing unknown segment.")
|
||||||
|
|
||||||
|
if t == "{":
|
||||||
|
counter += 1
|
||||||
|
elif t == "}":
|
||||||
|
counter -= 1
|
||||||
|
return
|
||||||
|
|
||||||
|
func ParseMeshNormals(mesh: XMesh):
|
||||||
|
ReadHead()
|
||||||
|
|
||||||
|
var normalCount = ReadInt()
|
||||||
|
|
||||||
|
for i in range(normalCount):
|
||||||
|
mesh.normals.push_back(ReadVector3())
|
||||||
|
|
||||||
|
var faceCount = ReadInt()
|
||||||
|
if faceCount != mesh.indices.size() / 3:
|
||||||
|
assert(false, "Normal face count does not match vertex face count.")
|
||||||
|
|
||||||
|
for i in range(faceCount):
|
||||||
|
var numIndices = ReadInt()
|
||||||
|
for i1 in range(numIndices):
|
||||||
|
mesh.normalIndices.push_back(ReadInt())
|
||||||
|
TestForSeparator()
|
||||||
|
|
||||||
|
CheckForClosingBrace()
|
||||||
|
|
||||||
|
func ParseMeshTextureCoords(mesh: XMesh):
|
||||||
|
ReadHead()
|
||||||
|
if mesh.textureCount + 1 > MAX_TEX_COORDS:
|
||||||
|
assert(false, "Too many sets of texture coordinates")
|
||||||
|
|
||||||
|
var numCoords = ReadInt()
|
||||||
|
if numCoords != mesh.verts.size():
|
||||||
|
assert(false, "Texture coord count does not match vertex count")
|
||||||
|
|
||||||
|
for i in range(numCoords):
|
||||||
|
mesh.uvs.push_back(ReadVector2())
|
||||||
|
|
||||||
|
mesh.textureCount += 1
|
||||||
|
|
||||||
|
CheckForClosingBrace()
|
||||||
|
|
||||||
|
func ParseMeshVertexColors(mesh: XMesh):
|
||||||
|
pass
|
||||||
|
|
||||||
|
func ParseFrame(parent: Node = null):
|
||||||
|
var name = ReadHead()
|
||||||
|
var node = Node3D.new()
|
||||||
|
node.name = name
|
||||||
|
if parent:
|
||||||
|
parent.add_child(node)
|
||||||
|
else:
|
||||||
|
scene.add_child(node)
|
||||||
|
|
||||||
|
while true:
|
||||||
|
var objectName = GetNextToken()
|
||||||
|
print(str("\"",objectName,"\""))
|
||||||
|
if not objectName:
|
||||||
|
assert(false, "Unexpected end of file reached while parsing frame")
|
||||||
|
return
|
||||||
|
if objectName == "}":
|
||||||
|
break
|
||||||
|
elif objectName == "Frame":
|
||||||
|
ParseFrame(node)
|
||||||
|
elif objectName == "FrameTransformMatrix":
|
||||||
|
# TODO: Do something with this?
|
||||||
|
print(ParseTransformationMatrix())
|
||||||
|
elif objectName == "Mesh":
|
||||||
|
ParseMesh(node)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
func ReadRGB() -> Color:
|
||||||
|
var r = ReadFloat()
|
||||||
|
var g = ReadFloat()
|
||||||
|
var b = ReadFloat()
|
||||||
|
TestForSeparator()
|
||||||
|
return Color(r, g, b, 1)
|
||||||
|
|
||||||
|
func ReadRGBA() -> Color:
|
||||||
|
var r = ReadFloat()
|
||||||
|
var g = ReadFloat()
|
||||||
|
var b = ReadFloat()
|
||||||
|
var a = ReadFloat()
|
||||||
|
TestForSeparator()
|
||||||
|
return Color(r, g, b, a)
|
||||||
|
|
||||||
|
func ParseTextureFilename():
|
||||||
|
ReadHead()
|
||||||
|
var name = GetNextToken()
|
||||||
|
|
||||||
|
func ParseMaterial():
|
||||||
|
var material = StandardMaterial3D.new()
|
||||||
|
var name = ReadHead()
|
||||||
|
if not name:
|
||||||
|
name = str("material", lineNumber)
|
||||||
|
var diffuse = ReadRGBA()
|
||||||
|
var specularExponent = ReadFloat()
|
||||||
|
var specular = ReadRGB()
|
||||||
|
var emissive = ReadRGB()
|
||||||
|
|
||||||
|
while true:
|
||||||
|
var objectName = GetNextToken()
|
||||||
|
if not objectName:
|
||||||
|
assert(false, "Unexpected end of file while parsing mesh material")
|
||||||
|
elif objectName == "}":
|
||||||
|
break
|
||||||
|
elif objectName == "TextureFilename" or objectName == "TextureFileName":
|
||||||
|
|
||||||
|
|
||||||
|
func ParseFile():
|
||||||
|
while true:
|
||||||
|
var objectName = GetNextToken()
|
||||||
|
print(str("\"",objectName,"\""))
|
||||||
|
if not objectName:
|
||||||
|
break
|
||||||
|
if objectName == "template":
|
||||||
|
ParseTemplate()
|
||||||
|
elif objectName == "Frame":
|
||||||
|
ParseFrame()
|
||||||
|
elif objectName == "Mesh":
|
||||||
|
ParseMesh(scene)
|
||||||
|
elif objectName == "AnimTicksPerSecond":
|
||||||
|
ParseUnknownDataObject()
|
||||||
|
elif objectName == "AnimationSet":
|
||||||
|
ParseUnknownDataObject()
|
||||||
|
elif objectName == "Material":
|
||||||
|
materials.push_back(ParseMaterial())
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
#static func LoadModel(filePath: String):
|
||||||
|
#var sillyPath = str("res://", filePath.replace("/Map/", "/map/"))
|
||||||
|
#var file = FileAccess.open(sillyPath, FileAccess.READ)
|
||||||
|
#
|
||||||
|
## 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)
|
||||||
|
#
|
||||||
|
#var fileLines = file.get_as_text(true).split("\n")
|
||||||
|
#
|
||||||
|
#var meshDataStart = false
|
||||||
|
#var hitMeshOnce = false
|
||||||
|
#var indexDataStart = false
|
||||||
|
#var meshTextureCoordsStart = false
|
||||||
|
#var hitTexCoordsOnce = false
|
||||||
|
#var textureNameStart = false
|
||||||
|
#var hitTextureOnce = false
|
||||||
|
#var textureName = ""
|
||||||
|
#var texture: Texture2D = null
|
||||||
|
#var meshDataLength = -1
|
||||||
|
#var uvsDataLength = -1
|
||||||
|
#var indexDataLength = -1
|
||||||
|
#var verts = PackedVector3Array()
|
||||||
|
#var uvs = PackedVector2Array()
|
||||||
|
#var indexes = PackedInt32Array()
|
||||||
|
## oh god oh fuck i hope not
|
||||||
|
#var is3dWorldStudioFile = false
|
||||||
|
#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 and meshDataLength == -1:
|
||||||
|
#meshDataLength = int(line.strip_edges().split(";")[0])
|
||||||
|
#elif indexDataStart and indexDataLength == -1:
|
||||||
|
#indexDataLength = int(line.strip_edges().split(";")[0])
|
||||||
|
#elif meshDataStart:
|
||||||
|
#var pointData = line.strip_edges().split(";")
|
||||||
|
#if pointData.size() == 5:
|
||||||
|
#meshDataStart = false
|
||||||
|
#indexDataStart = true
|
||||||
|
#verts.push_back(Vector3(-float(pointData[0]), float(pointData[1]), float(pointData[2])))
|
||||||
|
#elif indexDataStart:
|
||||||
|
#var indexParts = line.strip_edges().split(";")
|
||||||
|
#if indexParts.size() == 4:
|
||||||
|
#indexDataStart = false
|
||||||
|
#var indexData = indexParts[1].split(",")
|
||||||
|
#var amount = int(indexParts[0])
|
||||||
|
#for i in range(amount):
|
||||||
|
#indexes.push_back(int(indexData[i]))
|
||||||
|
#elif textureNameStart:
|
||||||
|
#textureName = line.strip_edges().split(";")[0].replace("\"", "")
|
||||||
|
#var texturePath = str("GFX/map/Props/", textureName)
|
||||||
|
#texture = Global.GetTextureFromCache(texturePath)
|
||||||
|
#if not texture:
|
||||||
|
#texture = Global.LoadTexture(texturePath)
|
||||||
|
#textureNameStart = false
|
||||||
|
#elif meshTextureCoordsStart:
|
||||||
|
#if uvsDataLength == -1:
|
||||||
|
#uvsDataLength = int(line.strip_edges().split(";")[0])
|
||||||
|
#else:
|
||||||
|
## 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:
|
||||||
|
#meshTextureCoordsStart = false
|
||||||
|
#else:
|
||||||
|
#uvs.push_back(Vector2(float(uvParts[0]), float(uvParts[1])))
|
||||||
|
#
|
||||||
|
#if line.strip_edges().contains("Mesh ") and not hitMeshOnce:
|
||||||
|
#meshDataStart = true
|
||||||
|
#hitMeshOnce = true
|
||||||
|
#elif line.strip_edges().contains("TextureFilename") and not hitTextureOnce:
|
||||||
|
#textureNameStart = true
|
||||||
|
#hitTextureOnce = true
|
||||||
|
#elif line.strip_edges().contains("MeshTextureCoords") and not hitTexCoordsOnce:
|
||||||
|
#meshTextureCoordsStart = true
|
||||||
|
#hitTexCoordsOnce = true
|
||||||
|
#
|
||||||
|
#var mesh = MeshInstance3D.new()
|
||||||
|
#var arr_mesh = ArrayMesh.new()
|
||||||
|
#var arr = []
|
||||||
|
#arr.resize(Mesh.ARRAY_MAX)
|
||||||
|
#
|
||||||
|
#arr[Mesh.ARRAY_VERTEX]=verts
|
||||||
|
#arr[Mesh.ARRAY_TEX_UV]=uvs
|
||||||
|
#arr[Mesh.ARRAY_INDEX]=indexes
|
||||||
|
#
|
||||||
|
#var meshInstance = MeshInstance3D.new()
|
||||||
|
#arr_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr)
|
||||||
|
#meshInstance.mesh = arr_mesh
|
||||||
|
#var mat = StandardMaterial3D.new()
|
||||||
|
##mat.albedo_color = Color(randi() % 255 / 255.0, randi() % 255 / 255.0, randi() % 255 / 255.0)
|
||||||
|
#mat.albedo_texture = texture
|
||||||
|
##mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA_DEPTH_PRE_PASS if activeAlbedoHasAlpha else BaseMaterial3D.TRANSPARENCY_DISABLED
|
||||||
|
#meshInstance.set_surface_override_material(0, mat)
|
||||||
|
#meshInstance.create_trimesh_collision()
|
||||||
|
#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
|
||||||
|
|
10
src/objects/X/XMesh.gd
Normal file
10
src/objects/X/XMesh.gd
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
class_name XMesh
|
||||||
|
|
||||||
|
var parent: Node
|
||||||
|
var name: String
|
||||||
|
var verts: PackedVector3Array = PackedVector3Array()
|
||||||
|
var indices: PackedInt32Array = PackedInt32Array()
|
||||||
|
var normals: PackedVector3Array = PackedVector3Array()
|
||||||
|
var normalIndices: PackedInt32Array = PackedInt32Array()
|
||||||
|
var uvs: PackedVector2Array = PackedVector2Array()
|
||||||
|
var textureCount: int = 0
|
Loading…
Add table
Reference in a new issue