166 lines
4.1 KiB
GDScript
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
|