class_name RMesh static func ReadString(reader:BufferStuffReader): var length = reader.readInt() return reader.readBuffer(length).get_string_from_ascii() const WORLD_SCALE = 0.010 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 RMESH_LOAD_COUNT = 0 static func LoadRMesh(parentNode: Node3D, file: String): var correctedPath = file.replace("\\", "/") var fileName = correctedPath.split("/")[-1] var fileHandle = FileAccess.open(str("res://", correctedPath), FileAccess.READ) var reader = BufferStuffReader.create(fileHandle.get_buffer(fileHandle.get_length())) fileHandle.close() var header = ReadString(reader) var hasTriggerBox = header == "RoomMesh.HasTriggerBox" if header != "RoomMesh": print(str(correctedPath, " is Not RMESH")) return var scene = Node3D.new() scene.name = str(fileName, "_", RMESH_LOAD_COUNT) RMESH_LOAD_COUNT += 1 parentNode.add_child(scene) var count: int = 0 var count2: int = 0 file = StripFilename(file) #print(file) var i var j var k var x var y var z var yaw var temp1i:int var temp2i:int var temp3i:int var temp1 var temp2 var temp3 var temp1s:String var temp2s:String var blendType: int var textureName: String #drawn meshes var Opaque = Mesh.new() var Alpha = Mesh.new() count = reader.readInt() var childMesh var surf var tex: Array = [0, 0] var brush var isAlpha:float var u:float var v:float var activeAlbedo: Texture2D = null var activeAlbedoHasAlpha = false var activeBump: Texture2D = null for i1 in range(count): # drawn mesh childMesh = Mesh.new() var vertices = PackedVector3Array() var uvs = PackedVector2Array() var tris = PackedInt32Array() #surf=CreateSurface(childMesh) #brush=CreateBrush() tex[0] = 0 tex[1] = 0 isAlpha = 0 for j2 in range(2): blendType = reader.readUByte() if blendType != 0: textureName = ReadString(reader) tex[j2] = Global.GetTextureFromCache(textureName) if tex[j2] == null: # texture is not in cache if blendType < 3: tex[j2] = Global.LoadTexture(str(file, textureName)) else: tex[j2] = Global.LoadTexture(str(file, textureName)) # TODO: load with alpha #if tex[j2] != 0: #If blendType=1 Then TextureBlend tex[j2],5 #If Instr(Lower(textureName),"_lm")<>0 Then #TextureBlend tex[j2],3 #EndIf #AddTextureToCache(tex[j2]) #EndIf if tex[j2] != null: isAlpha = 2 if blendType == 3: isAlpha = 1 #TextureCoords tex[j2],1-j activeAlbedo = EMPTY_TEXTURE activeAlbedoHasAlpha = isAlpha == 1 #if isAlpha == 1: if tex[1] != null: #TextureBlend tex[1],2 #BrushTexture brush,tex[1],0,0 activeAlbedo = tex[1] else: #BrushTexture brush,blankTexture,0,0 activeAlbedo = EMPTY_TEXTURE #else: #if tex[0] != null and tex[1] != null: #bumptex% = GetBumpFromCache(StripPath(TextureName(tex[1]))) #;If bumptex<>0 Then #; DebugLog StripPath(TextureName(bumptex)) #; Stop #;EndIf #For j=0 To 1 #BrushTexture brush,tex[j],0,j+1+(bumptex<>0) #Next # #BrushTexture brush,AmbientLightRoomTex,0 #If (bumptex<>0) Then #BrushTexture brush,bumptex,0,1 #EndIf #Else #For j=0 To 1 #If tex[j]<>0 Then #BrushTexture brush,tex[j],0,j #Else #BrushTexture brush,blankTexture,0,j #EndIf #Next #EndIf #EndIf #surf=CreateSurface(childMesh) #if isAlpha > 0: #PaintSurface surf,brush #FreeBrush brush : brush = 0 count2 = reader.readInt() # vertices for j2 in range(count2): # world coords x = -reader.readFloat() * WORLD_SCALE y = reader.readFloat() * WORLD_SCALE z = reader.readFloat() * WORLD_SCALE #vertex = AddVertex(surf,x,y,z) vertices.push_back(Vector3(x, y, z)) #var meshInstance = MeshInstance3D.new() #meshInstance.mesh = QuadMesh.new() #var mat = StandardMaterial3D.new() #mat.albedo_color = Color.RED #mat.billboard_mode = BaseMaterial3D.BILLBOARD_ENABLED #meshInstance.set_surface_override_material(0, mat) #scene.add_child(meshInstance) #meshInstance.global_position.x = x #meshInstance.global_position.y = y #meshInstance.global_position.z = z # texture coords for k2 in range(0, 1): u = reader.readFloat() v = reader.readFloat() #VertexTexCoords surf,vertex,u,v,0.0,k uvs.push_back(Vector2(u, v)) reader.readFloat() reader.readFloat() # colors temp1i = reader.readUByte() temp2i = reader.readUByte() temp3i = reader.readUByte() #print(str("Got vertex. Pos:", Vector3(x, y, z), ", UV:", Vector2(u, v), ", Color:", Color(temp1i, temp2i, temp3i))) #VertexColor surf,vertex,temp1i,temp2i,temp3i,1.0 count2 = reader.readInt() # polys for j2 in range(count2): tris.push_back(reader.readInt()) tris.push_back(reader.readInt()) tris.push_back(reader.readInt()) #AddTriangle(surf,temp1i,temp2i,temp3i) if isAlpha == 1: #AddMesh childMesh,Alpha #EntityAlpha childMesh,0.0 #print("loaded transparent face") x else: x #AddMesh childMesh,Opaque #EntityParent childMesh,collisionMeshes #EntityAlpha childMesh,0.0 #EntityType childMesh,HIT_MAP #EntityPickMode childMesh,2 # #;make collision double-sided #Local flipChild% = CopyMesh(childMesh) #FlipMesh(flipChild) #AddMesh flipChild,childMesh #FreeEntity flipChild #print("loaded opaque geometry") #var st = SurfaceTool.new() #st.begin(Mesh.PRIMITIVE_LINE_STRIP) #var mat = StandardMaterial3D.new() #mat.albedo_color = Color.RED #st.set_material(mat) #for i2 in range(len(vertices)): ##st.add(uvs[i2]) #st.add_vertex(vertices[i2]) #st. var mesh = MeshInstance3D.new() var arr_mesh = ArrayMesh.new() var arr = [] arr.resize(Mesh.ARRAY_MAX) arr[Mesh.ARRAY_VERTEX]=vertices arr[Mesh.ARRAY_TEX_UV]=uvs arr[Mesh.ARRAY_INDEX]=tris 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 = activeAlbedo 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() scene.add_child(meshInstance) #print("YOYOYO MARKER") #Local hiddenMesh% #hiddenMesh=CreateMesh() #var collisionMesh = ArrayMesh.new() # #var collision = CollisionPolygon3D.new() #collision. count = reader.readInt() # invisible collision mesh for i1 in range(count): var verts = PackedVector3Array() var tris = PackedInt32Array() #surf=CreateSurface(hiddenMesh) count2 = reader.readInt() # vertices for j2 in range(count2): # world coords x = -reader.readFloat() * WORLD_SCALE y = reader.readFloat() * WORLD_SCALE z = reader.readFloat() * WORLD_SCALE verts.push_back(Vector3(x, y, z)) count2 = reader.readInt() # polys for j2 in range(count2): temp1i = reader.readInt() temp2i = reader.readInt() temp3i = reader.readInt() tris.push_back(temp1i) tris.push_back(temp2i) tris.push_back(temp3i) tris.push_back(temp1i) tris.push_back(temp3i) tris.push_back(temp2i) var mesh = MeshInstance3D.new() var arr_mesh = ArrayMesh.new() var arr = [] arr.resize(Mesh.ARRAY_MAX) arr[Mesh.ARRAY_VERTEX]=verts arr[Mesh.ARRAY_INDEX]=tris 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_color = Color.GREEN meshInstance.set_surface_override_material(0, mat) meshInstance.create_trimesh_collision() meshInstance.visible = true scene.add_child(meshInstance) # trigger boxes if hasTriggerBox: #print("TriggerBoxEnable") var triggerBoxAmount = reader.readInt() for tb in range(triggerBoxAmount): var tbVerts = PackedVector3Array() var tbIndexes = PackedInt32Array() #rt\TempTriggerbox[tb] = CreateMesh(rt\obj) count = reader.readInt() for i1 in range(count): #surf=CreateSurface(rt\TempTriggerbox[tb]) count2 = reader.readInt() for j2 in range(count2): x = -reader.readFloat() * WORLD_SCALE y = reader.readFloat() * WORLD_SCALE z = reader.readFloat() * WORLD_SCALE tbVerts.push_back(Vector3(x, y, z)) #vertex=AddVertex(surf,x,y,z) count2 = reader.readInt() for j2 in range(count2): temp1i = reader.readInt() temp2i = reader.readInt() temp3i = reader.readInt() tbIndexes.push_back(temp1i) tbIndexes.push_back(temp2i) tbIndexes.push_back(temp3i) tbIndexes.push_back(temp1i) tbIndexes.push_back(temp3i) tbIndexes.push_back(temp2i) #AddTriangle(surf,temp1i,temp2i,temp3i) #AddTriangle(surf,temp1i,temp3i,temp2i) var mesh = MeshInstance3D.new() var arr_mesh = ArrayMesh.new() var arr = [] arr.resize(Mesh.ARRAY_MAX) arr[Mesh.ARRAY_VERTEX]=tbVerts arr[Mesh.ARRAY_INDEX]=tbIndexes 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_color = Color.RED meshInstance.set_surface_override_material(0, mat) meshInstance.create_trimesh_collision() #meshInstance.visible = false scene.add_child(meshInstance) meshInstance.name = ReadString(reader) #rt\TempTriggerboxName[tb] = ReadString(f) count = reader.readInt() # point entities for i1 in range(count): temp1s = ReadString(reader) #print(str("POINT ENTITY: ", temp1s)) if temp1s == "screen": temp1 = -reader.readFloat() * WORLD_SCALE temp2 = reader.readFloat() * WORLD_SCALE temp3 = reader.readFloat() * WORLD_SCALE temp2s = ReadString(reader) if temp1 != 0 or temp2 != 0 or temp3 != 0: var ts = TempScreen.new() ts.x = temp1 ts.y = temp2 ts.z = temp3 ts.imgpath = temp2s #ts\roomtemplate = rt elif temp1s == "waypoint": temp1 = -reader.readFloat() * WORLD_SCALE temp2 = reader.readFloat() * WORLD_SCALE temp3 = reader.readFloat() * WORLD_SCALE var marker = Marker3D.new() marker.position = Vector3(temp1, temp2, temp3) scene.add_child(marker) #Local w.TempWayPoints = New TempWayPoints #w\roomtemplate = rt #w\x = temp1 #w\y = temp2 #w\z = temp3 # elif temp1s == "light": temp1 = -reader.readFloat() * WORLD_SCALE temp2 = reader.readFloat() * WORLD_SCALE temp3 = reader.readFloat() * WORLD_SCALE if temp1 != 0 or temp2 != 0 or temp3 != 0: var range = reader.readFloat() / 2000.0 var lcolor = ReadString(reader).split(" ") var intensity = min(reader.readFloat() * 0.8, 1.0) #print(str("light. Range: ", range, ", lcolor: ", lcolor, ", intensity:", intensity)) var r = int(lcolor[0]) / 255 * intensity var g = int(lcolor[1]) / 255 * intensity var b = int(lcolor[2]) / 255 * intensity var pointlight = OmniLight3D.new() pointlight.light_color = Color(r, g, b) #scene.add_child(pointlight) pointlight.position = Vector3(temp1, temp2, temp3) #AddTempLight(rt, temp1,temp2,temp3, 2, range, r,g,b) else: reader.readFloat() ReadString(reader) reader.readFloat() elif temp1s == "spotlight": temp1 = -reader.readFloat() * WORLD_SCALE temp2 = reader.readFloat() * WORLD_SCALE temp3 = reader.readFloat() * WORLD_SCALE if temp1 != 0 or temp2 != 0 or temp3 != 0: var range = reader.readFloat() / 2000.0 var lcolor = ReadString(reader).split(" ") var intensity = min(reader.readFloat() * 0.8, 1.0) #r%=Int(Piece(lcolor,1," "))*intensity #g%=Int(Piece(lcolor,2," "))*intensity #b%=Int(Piece(lcolor,3," "))*intensity # #Local lt.LightTemplates = AddTempLight(rt, temp1,temp2,temp3, 2, range, r,g,b) var angles = ReadString(reader) #pitch#=Piece(angles,1," ") #yaw#=Piece(angles,2," ") #lt\pitch = pitch #lt\yaw = yaw # var innerconeangle = reader.readInt() var outerconeangle = reader.readInt() #print(str("spotlight. Range: ", range, ", lcolor: ", lcolor, ", intensity:", intensity, ", angles: ", angles, ", innerconeangle: ", innerconeangle, ", outerconeangle: ", outerconeangle)) #lt\innerconeangle = ReadInt(f) #lt\outerconeangle = ReadInt(f) else: reader.readFloat() ReadString(reader) reader.readFloat() ReadString(reader) reader.readInt() reader.readInt() elif temp1s == "soundemitter": reader.readFloat() reader.readFloat() reader.readFloat() reader.readInt() reader.readFloat() #temp1i=0 #For j = 0 To MaxRoomEmitters-1 #If rt\TempSoundEmitter[j]=0 Then #rt\TempSoundEmitterX[j]=ReadFloat(f)*RoomScale #rt\TempSoundEmitterY[j]=ReadFloat(f)*RoomScale #rt\TempSoundEmitterZ[j]=ReadFloat(f)*RoomScale #rt\TempSoundEmitter[j]=ReadInt(f) # #rt\TempSoundEmitterRange[j]=ReadFloat(f) #temp1i=1 #Exit #EndIf #Next # #If temp1i=0 Then #ReadFloat(f) #ReadFloat(f) #ReadFloat(f) #ReadInt(f) #ReadFloat(f) #EndIf # elif temp1s == "playerstart": temp1 = -reader.readFloat() temp2 = reader.readFloat() temp3 = reader.readFloat() var angles = ReadString(reader) #pitch = Piece(angles,1," ") #yaw#=Piece(angles,2," ") #roll#=Piece(angles,3," ") #If cam Then #PositionEntity cam,temp1,temp2,temp3 #RotateEntity cam,pitch,yaw,roll #EndIf elif temp1s == "model": var modelPath = ReadString(reader) if modelPath != "": #Local model = CreatePropObj("GFX\Map\Props\"+modelPath);LoadMesh("GFX\Map\Props\"+modelPath) var model = X.LoadModel(str("GFX/Map/Props/", modelPath)) scene.add_child(model) # temp1 = -reader.readFloat() * WORLD_SCALE temp2 = reader.readFloat() * WORLD_SCALE temp3 = reader.readFloat() * WORLD_SCALE model.position = Vector3(temp1, temp2, temp3) #PositionEntity model,temp1,temp2,temp3 # temp1 = reader.readFloat() temp2 = reader.readFloat() temp3 = reader.readFloat() model.rotation = Vector3(deg_to_rad(temp1), deg_to_rad(temp2), deg_to_rad(temp3)) #RotateEntity model,temp1,temp2,temp3 # temp1 = reader.readFloat() * WORLD_SCALE temp2 = reader.readFloat() * WORLD_SCALE temp3 = reader.readFloat() * WORLD_SCALE model.scale = Vector3(temp1, temp2, temp3) #ScaleEntity model,temp1,temp2,temp3 # #EntityParent model,Opaque #EntityType model,HIT_MAP #EntityPickMode model,2 #Else #DebugLog "file = 0" #temp1=ReadFloat(f) : temp2=ReadFloat(f) : temp3=ReadFloat(f) #DebugLog temp1+", "+temp2+", "+temp3 # #;Stop #EndIf #Next # #Local obj% # #temp1i=CopyMesh(Alpha) #FlipMesh temp1i #AddMesh temp1i,Alpha #FreeEntity temp1i # #If brush <> 0 Then FreeBrush brush # #AddMesh Alpha,Opaque #FreeEntity Alpha # #EntityFX Opaque,3 # #EntityAlpha hiddenMesh,0.0 #EntityAlpha Opaque,1.0 # #;EntityType Opaque,HIT_MAP #EntityType hiddenMesh,HIT_MAP #FreeTexture blankTexture # #;AddMesh hiddenMesh,BigRoomMesh # #obj=CreatePivot() #CreatePivot(obj) ;skip "meshes" object #EntityParent Opaque,obj #EntityParent hiddenMesh,obj #CreatePivot(obj) ;skip "pointentites" object #CreatePivot(obj) ;skip "solidentites" object #EntityParent collisionMeshes,obj # #CloseFile f # #CatchErrors("LoadRMesh") #Return obj%