mirror of https://github.com/kivy/kivy.git
148 lines
4.6 KiB
Python
148 lines
4.6 KiB
Python
class MeshData(object):
|
|
def __init__(self, **kwargs):
|
|
self.name = kwargs.get("name")
|
|
self.vertex_format = [
|
|
(b'v_pos', 3, 'float'),
|
|
(b'v_normal', 3, 'float'),
|
|
(b'v_tc0', 2, 'float')]
|
|
self.vertices = []
|
|
self.indices = []
|
|
|
|
def calculate_normals(self):
|
|
for i in range(len(self.indices) / (3)):
|
|
fi = i * 3
|
|
v1i = self.indices[fi]
|
|
v2i = self.indices[fi + 1]
|
|
v3i = self.indices[fi + 2]
|
|
|
|
vs = self.vertices
|
|
p1 = [vs[v1i + c] for c in range(3)]
|
|
p2 = [vs[v2i + c] for c in range(3)]
|
|
p3 = [vs[v3i + c] for c in range(3)]
|
|
|
|
u, v = [0, 0, 0], [0, 0, 0]
|
|
for j in range(3):
|
|
v[j] = p2[j] - p1[j]
|
|
u[j] = p3[j] - p1[j]
|
|
|
|
n = [0, 0, 0]
|
|
n[0] = u[1] * v[2] - u[2] * v[1]
|
|
n[1] = u[2] * v[0] - u[0] * v[2]
|
|
n[2] = u[0] * v[1] - u[1] * v[0]
|
|
|
|
for k in range(3):
|
|
self.vertices[v1i + 3 + k] = n[k]
|
|
self.vertices[v2i + 3 + k] = n[k]
|
|
self.vertices[v3i + 3 + k] = n[k]
|
|
|
|
|
|
class ObjFile:
|
|
def finish_object(self):
|
|
if self._current_object is None:
|
|
return
|
|
|
|
mesh = MeshData()
|
|
idx = 0
|
|
for f in self.faces:
|
|
verts = f[0]
|
|
norms = f[1]
|
|
tcs = f[2]
|
|
for i in range(3):
|
|
# get normal components
|
|
n = (0.0, 0.0, 0.0)
|
|
if norms[i] != -1:
|
|
n = self.normals[norms[i] - 1]
|
|
|
|
# get texture coordinate components
|
|
t = (0.0, 0.0)
|
|
if tcs[i] != -1:
|
|
t = self.texcoords[tcs[i] - 1]
|
|
|
|
# get vertex components
|
|
v = self.vertices[verts[i] - 1]
|
|
|
|
data = [v[0], v[1], v[2], n[0], n[1], n[2], t[0], t[1]]
|
|
mesh.vertices.extend(data)
|
|
|
|
tri = [idx, idx + 1, idx + 2]
|
|
mesh.indices.extend(tri)
|
|
idx += 3
|
|
|
|
self.objects[self._current_object] = mesh
|
|
# mesh.calculate_normals()
|
|
self.faces = []
|
|
|
|
def __init__(self, filename, swapyz=False):
|
|
"""Loads a Wavefront OBJ file. """
|
|
self.objects = {}
|
|
self.vertices = []
|
|
self.normals = []
|
|
self.texcoords = []
|
|
self.faces = []
|
|
|
|
self._current_object = None
|
|
|
|
material = None
|
|
for line in open(filename, "r"):
|
|
if line.startswith('#'):
|
|
continue
|
|
if line.startswith('s'):
|
|
continue
|
|
values = line.split()
|
|
if not values:
|
|
continue
|
|
if values[0] == 'o':
|
|
self.finish_object()
|
|
self._current_object = values[1]
|
|
# elif values[0] == 'mtllib':
|
|
# self.mtl = MTL(values[1])
|
|
# elif values[0] in ('usemtl', 'usemat'):
|
|
# material = values[1]
|
|
if values[0] == 'v':
|
|
v = list(map(float, values[1:4]))
|
|
if swapyz:
|
|
v = v[0], v[2], v[1]
|
|
self.vertices.append(v)
|
|
elif values[0] == 'vn':
|
|
v = list(map(float, values[1:4]))
|
|
if swapyz:
|
|
v = v[0], v[2], v[1]
|
|
self.normals.append(v)
|
|
elif values[0] == 'vt':
|
|
self.texcoords.append(map(float, values[1:3]))
|
|
elif values[0] == 'f':
|
|
face = []
|
|
texcoords = []
|
|
norms = []
|
|
for v in values[1:]:
|
|
w = v.split('/')
|
|
face.append(int(w[0]))
|
|
if len(w) >= 2 and len(w[1]) > 0:
|
|
texcoords.append(int(w[1]))
|
|
else:
|
|
texcoords.append(-1)
|
|
if len(w) >= 3 and len(w[2]) > 0:
|
|
norms.append(int(w[2]))
|
|
else:
|
|
norms.append(-1)
|
|
self.faces.append((face, norms, texcoords, material))
|
|
self.finish_object()
|
|
|
|
|
|
def MTL(filename):
|
|
contents = {}
|
|
mtl = None
|
|
return
|
|
for line in open(filename, "r"):
|
|
if line.startswith('#'):
|
|
continue
|
|
values = line.split()
|
|
if not values:
|
|
continue
|
|
if values[0] == 'newmtl':
|
|
mtl = contents[values[1]] = {}
|
|
elif mtl is None:
|
|
raise ValueError("mtl file doesn't start with newmtl stmt")
|
|
mtl[values[0]] = values[1:]
|
|
return contents
|