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")
|
||||
#add_child(B3D.Load("GFX\\apache.b3d"))
|
||||
|
||||
X.LoadModel("res://GFX/map/Door01.x")
|
||||
|
||||
#DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
|
||||
|
||||
#RMesh.LoadRMesh(self, roomInfo["mesh path"])
|
||||
|
||||
#CreateMap()
|
||||
IntroEnabled = true
|
||||
LoadRoomTemplates("Data/rooms.ini")
|
||||
CreateMap()
|
||||
#LoadRoomTemplates("Data/rooms.ini")
|
||||
#CreateMap()
|
||||
|
||||
var IntroEnabled: bool
|
||||
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 d = Door.new()
|
||||
doors.push_back(d)
|
||||
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.scale.x = 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
|
||||
#EntityAlpha d\frameobj, 0.0
|
||||
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.scale.x = 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)
|
||||
elif big == 3:
|
||||
print("DOORS: Creating ElevatorDoor in " + room.RoomTemplate.Name, ", X: ", x, ", Y: ", y, " Z: ", z)
|
||||
print("TODO: ELEVATOR DOOR!")
|
||||
#for d2 = Each Doors
|
||||
#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
|
||||
#d\frameobj = CopyEntity(DoorFrameOBJ)
|
||||
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.scale.x = (204.0 * Constants.RoomScale) / X.MeshWidth(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].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[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
|
||||
#EntityColor d\DoorHitOBJ,255,0,0
|
||||
#HideEntity d\DoorHitOBJ
|
||||
|
||||
|
||||
return d
|
||||
|
||||
func FillRoom(r:Room):
|
||||
|
|
|
@ -1,7 +1,24 @@
|
|||
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
|
||||
# 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:
|
||||
var minX: float = 0
|
||||
|
@ -34,118 +51,578 @@ static func MeshHeight(mesh: Node) -> float:
|
|||
static func MeshDepth(mesh: Node) -> float:
|
||||
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):
|
||||
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)
|
||||
|
||||
# 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 x = X.new()
|
||||
|
||||
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
|
||||
x.majorVersion = 0
|
||||
x.minorVersion = 0
|
||||
x.isBinaryFormat = false
|
||||
x.binaryFloatSize = 0
|
||||
x.binaryNumCount = 0
|
||||
x.p = 0
|
||||
x.end = file.get_length()
|
||||
|
||||
x.file = file.get_buffer(x.end)
|
||||
file.close()
|
||||
|
||||
if x.GetStringBytes(x.p, x.p + 4) != "xof ":
|
||||
assert(false, "This is not a DirectX file!")
|
||||
return
|
||||
|
||||
x.majorVersion = int(x.GetStringBytes(4, 6))
|
||||
x.minorVersion = int(x.GetStringBytes(6, 8))
|
||||
|
||||
x.compressed = false
|
||||
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 stripLine == "{" or stripLine == "}":
|
||||
continue
|
||||
if x.isBinaryFormat or x.compressed:
|
||||
assert(false, "Binary and Compressed files are currently unsupported!")
|
||||
return
|
||||
|
||||
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])))
|
||||
x.binaryFloatSize = int(x.GetStringBytes(12, 16))
|
||||
|
||||
if x.binaryFloatSize != 32 and x.binaryFloatSize != 64:
|
||||
assert(false, str("Unknown float size ", x.binaryFloatSize, " specified in DirectX file header."))
|
||||
|
||||
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
|
||||
x.p += 16
|
||||
|
||||
if x.compressed:
|
||||
# hard pass
|
||||
pass
|
||||
else:
|
||||
x.ReadUntilEndOfLine()
|
||||
|
||||
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()
|
||||
var arr_mesh = ArrayMesh.new()
|
||||
var arr = []
|
||||
arr.resize(Mesh.ARRAY_MAX)
|
||||
while p < end and GetStringBytes(p, p + 1) != " ":
|
||||
var tmp = GetStringBytes(p, p + 1)
|
||||
if tmp == ";" or tmp == "}" or tmp == "{" or tmp == ",":
|
||||
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
|
||||
arr[Mesh.ARRAY_TEX_UV]=uvs
|
||||
arr[Mesh.ARRAY_INDEX]=indexes
|
||||
assert(GetNextToken() == ";", "Semicolon expected.")
|
||||
|
||||
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()
|
||||
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
|
||||
var M11 = ReadFloat()
|
||||
var M21 = ReadFloat()
|
||||
var M31 = ReadFloat()
|
||||
var M41 = ReadFloat()
|
||||
var M12 = ReadFloat()
|
||||
var M22 = ReadFloat()
|
||||
var M32 = ReadFloat()
|
||||
var M42 = ReadFloat()
|
||||
var M13 = ReadFloat()
|
||||
var M23 = ReadFloat()
|
||||
var M33 = ReadFloat()
|
||||
var M43 = ReadFloat()
|
||||
var M14 = ReadFloat()
|
||||
var M24 = ReadFloat()
|
||||
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