material-maker/material_maker/tools/obj_loader/obj_loader.gd

166 lines
4.1 KiB
GDScript

extends Node
func _ready():
pass # Replace with function body.
func load_obj_file(path : String) -> ArrayMesh:
if path == null:
return null
var ext := path.get_extension()
if !ext.matchn("obj"):
print("given file isn't an OBJ mesh")
return null
var st := SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
var mdlFile := File.new()
var errorCheck = mdlFile.open(path, File.READ)
if errorCheck != OK:
print("cannot open file at path[", path,"]")
mdlFile.close()
return null
var newTriMsh : TriMesh = _import_obj(mdlFile)
mdlFile.close()
var hasTex := newTriMsh.uvs.size() > 0
var hasNrm := newTriMsh.normals.size() > 0
for i in newTriMsh.indices.size():
var triangle : Triangle = newTriMsh.indices[i]
if hasTex:
st.add_uv(newTriMsh.uvs[triangle.uv_id_0])
if hasNrm:
st.add_normal(newTriMsh.normals[triangle.nrm_id_0])
st.add_vertex(newTriMsh.vertices[triangle.id_0])
if hasTex:
st.add_uv(newTriMsh.uvs[triangle.uv_id_1])
if hasNrm:
st.add_normal(newTriMsh.normals[triangle.nrm_id_1])
st.add_vertex(newTriMsh.vertices[triangle.id_1])
if hasTex:
st.add_uv(newTriMsh.uvs[triangle.uv_id_2])
if hasNrm:
st.add_normal(newTriMsh.normals[triangle.nrm_id_2])
st.add_vertex(newTriMsh.vertices[triangle.id_2])
if !hasNrm:
st.generate_normals()
if hasTex:
st.generate_tangents()
var mdl : ArrayMesh = st.commit()
return mdl
func _obj_rel_indice(indice : Vector3, cur_vArr_size : int) -> Vector3:
var output := Vector3.ZERO
var indSign := indice.sign()
output.x = indice.x - 1 if (indSign.x >= 0) else cur_vArr_size + indice.x
output.y = indice.y - 1 if (indSign.y >= 0) else cur_vArr_size + indice.y
output.z = indice.z - 1 if (indSign.z >= 0) else cur_vArr_size + indice.z
return output
func _import_obj(mdlFile : File) -> TriMesh:
var newMsh := TriMesh.new()
while !mdlFile.eof_reached():
var mdlData := mdlFile.get_line()
if mdlData.begins_with("#"):
continue
var f2c = mdlData.substr(0, 2)
var lineData := mdlData.split(" ", false)
match f2c:
"v ":
var vertex := Vector3(
float(lineData[1]),
float(lineData[2]),
float(lineData[3])
)
newMsh.vertices.push_back(vertex)
"vt":
var uv := Vector2(
float(lineData[1]),
1.0 - float(lineData[2])
)
newMsh.uvs.push_back(uv)
"vn":
var normal := Vector3(
float(lineData[1]),
float(lineData[2]),
float(lineData[3])
)
newMsh.normals.push_back(normal)
"f ":
var misc = []
for i in lineData.size() - 1:
misc.push_back(lineData[i + 1].split("/"))
for i in misc.size() - 2:
var intVar : int = i + 2
var num : int = misc[intVar].size()
var vArr_size : int = newMsh.vertices.size()
var tArr_size : int = newMsh.uvs.size()
var nArr_size : int = newMsh.normals.size()
var faceIndices = Vector3(
int(misc[intVar][0]),
int(misc[intVar-1][0]),
int(misc[0][0]))
faceIndices = _obj_rel_indice(faceIndices, vArr_size)
var uvIndices : Vector3
if num >= 2:
uvIndices = Vector3(
int(misc[intVar][1]),
int(misc[intVar-1][1]),
int(misc[0][1]))
uvIndices = _obj_rel_indice(uvIndices, tArr_size)
var normIndices : Vector3
if num == 3:
normIndices = Vector3(
int(misc[intVar][2]),
int(misc[intVar-1][2]),
int(misc[0][2]))
normIndices = _obj_rel_indice(normIndices, nArr_size)
var triangle := Triangle.new()
triangle.id_0 = int(faceIndices.x)
triangle.id_1 = int(faceIndices.y)
triangle.id_2 = int(faceIndices.z)
triangle.uv_id_0 = int(uvIndices.x)
triangle.uv_id_1 = int(uvIndices.y)
triangle.uv_id_2 = int(uvIndices.z)
triangle.nrm_id_0 = int(normIndices.x)
triangle.nrm_id_1 = int(normIndices.y)
triangle.nrm_id_2 = int(normIndices.z)
newMsh.indices.push_back(triangle)
return newMsh
class TriMesh:
var vertices : Array
var normals : Array
var uvs : Array
var indices : Array
class Triangle:
var id_0 : int
var uv_id_0 : int
var nrm_id_0 : int
var id_1 : int
var uv_id_1 : int
var nrm_id_1 : int
var id_2 : int
var uv_id_2 : int
var nrm_id_2 : int