Added normals generation
This commit is contained in:
parent
e223695914
commit
ecc8cc8ac6
|
@ -1,7 +1,9 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from math import sqrt
|
||||||
|
|
||||||
class Vertex:
|
class Vertex:
|
||||||
def __init__(self, x = None, y = None, z = None):
|
def __init__(self, x = 0.0, y = 0.0, z = 0.0):
|
||||||
self.x = x
|
self.x = x
|
||||||
self.y = y
|
self.y = y
|
||||||
self.z = z
|
self.z = z
|
||||||
|
@ -12,6 +14,37 @@ class Vertex:
|
||||||
self.z = float(arr[2]) if len(arr) > 2 else None
|
self.z = float(arr[2]) if len(arr) > 2 else None
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def __add__(self, other):
|
||||||
|
return Vertex(self.x + other.x, self.y + other.y, self.z + other.z)
|
||||||
|
|
||||||
|
def norm2(self):
|
||||||
|
return self.x * self.x + self.y * self.y + self.z * self.z
|
||||||
|
|
||||||
|
def norm(self):
|
||||||
|
return sqrt(self.norm2())
|
||||||
|
|
||||||
|
def normalize(self):
|
||||||
|
norm = self.norm()
|
||||||
|
if abs(norm) > 0.0001:
|
||||||
|
self.x /= norm
|
||||||
|
self.y /= norm
|
||||||
|
self.z /= norm
|
||||||
|
|
||||||
|
def cross_product(v1, v2):
|
||||||
|
return Vertex(
|
||||||
|
v1.y * v2.z - v1.z * v2.y,
|
||||||
|
v1.z * v2.x - v1.x * v2.z,
|
||||||
|
v1.x * v2.y - v1.y * v2.x)
|
||||||
|
|
||||||
|
def from_points(v1, v2):
|
||||||
|
return Vertex(
|
||||||
|
v2.x - v1.x,
|
||||||
|
v2.y - v1.y,
|
||||||
|
v2.z - v1.z)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '(' + ", ".join([str(self.x), str(self.y), str(self.z)]) + ")"
|
||||||
|
|
||||||
Normal = Vertex
|
Normal = Vertex
|
||||||
TexCoord = Vertex
|
TexCoord = Vertex
|
||||||
|
|
||||||
|
@ -91,14 +124,65 @@ class ModelParser:
|
||||||
v1 = self.vertices[face.a.vertex]
|
v1 = self.vertices[face.a.vertex]
|
||||||
v2 = self.vertices[face.b.vertex]
|
v2 = self.vertices[face.b.vertex]
|
||||||
v3 = self.vertices[face.c.vertex]
|
v3 = self.vertices[face.c.vertex]
|
||||||
|
|
||||||
|
if face.a.normal is not None:
|
||||||
|
n1 = self.normals[face.a.normal]
|
||||||
|
n2 = self.normals[face.b.normal]
|
||||||
|
n3 = self.normals[face.c.normal]
|
||||||
|
|
||||||
|
if face.a.normal is not None:
|
||||||
|
gl.glNormal3f(n1.x, n1.y, n1.z)
|
||||||
gl.glVertex3f(v1.x, v1.y, v1.z)
|
gl.glVertex3f(v1.x, v1.y, v1.z)
|
||||||
|
|
||||||
|
if face.a.normal is not None:
|
||||||
|
gl.glNormal3f(n2.x, n2.y, n2.z)
|
||||||
gl.glVertex3f(v2.x, v2.y, v2.z)
|
gl.glVertex3f(v2.x, v2.y, v2.z)
|
||||||
|
|
||||||
|
if face.a.normal is not None:
|
||||||
|
gl.glNormal3f(n3.x, n3.y, n3.z)
|
||||||
gl.glVertex3f(v3.x, v3.y, v3.z)
|
gl.glVertex3f(v3.x, v3.y, v3.z)
|
||||||
|
|
||||||
gl.glEnd()
|
gl.glEnd()
|
||||||
|
|
||||||
if self.center_and_scale:
|
if self.center_and_scale:
|
||||||
gl.glPopMatrix()
|
gl.glPopMatrix()
|
||||||
|
|
||||||
|
def generate_vertex_normals(self):
|
||||||
|
self.normals = [Normal() for i in self.vertices]
|
||||||
|
|
||||||
|
for face in self.faces:
|
||||||
|
v1 = Vertex.from_points(self.vertices[face.a.vertex], self.vertices[face.b.vertex])
|
||||||
|
v2 = Vertex.from_points(self.vertices[face.a.vertex], self.vertices[face.c.vertex])
|
||||||
|
cross = Vertex.cross_product(v1, v2)
|
||||||
|
self.normals[face.a.vertex] += cross
|
||||||
|
self.normals[face.b.vertex] += cross
|
||||||
|
self.normals[face.c.vertex] += cross
|
||||||
|
|
||||||
|
for normal in self.normals:
|
||||||
|
normal.normalize()
|
||||||
|
|
||||||
|
for face in self.faces:
|
||||||
|
face.a.normal = face.a.vertex
|
||||||
|
face.b.normal = face.b.vertex
|
||||||
|
face.c.normal = face.c.vertex
|
||||||
|
|
||||||
|
def generate_face_normals(self):
|
||||||
|
|
||||||
|
self.normals = [Normal() for i in self.faces]
|
||||||
|
|
||||||
|
for (index, face) in enumerate(self.faces):
|
||||||
|
|
||||||
|
v1 = Vertex.from_points(self.vertices[face.a.vertex], self.vertices[face.b.vertex])
|
||||||
|
v2 = Vertex.from_points(self.vertices[face.a.vertex], self.vertices[face.c.vertex])
|
||||||
|
cross = Vertex.cross_product(v1, v2)
|
||||||
|
cross.normalize()
|
||||||
|
self.normals[index] = cross
|
||||||
|
|
||||||
|
face.a.normal = index
|
||||||
|
face.b.normal = index
|
||||||
|
face.c.normal = index
|
||||||
|
|
||||||
|
|
||||||
class BoundingBox:
|
class BoundingBox:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.min_x = +float('inf')
|
self.min_x = +float('inf')
|
||||||
|
|
|
@ -43,9 +43,14 @@ def main(args = {}):
|
||||||
glEnable(GL_BLEND)
|
glEnable(GL_BLEND)
|
||||||
glClearColor(0, 0, 0, 0)
|
glClearColor(0, 0, 0, 0)
|
||||||
|
|
||||||
|
glLightfv(GL_LIGHT0, GL_POSITION, [10,5,7])
|
||||||
|
glEnable(GL_LIGHTING)
|
||||||
|
glEnable(GL_LIGHT0)
|
||||||
|
|
||||||
running = True
|
running = True
|
||||||
|
|
||||||
model = load_model('./examples/link.obj')
|
model = load_model('./examples/cube.obj')
|
||||||
|
model.generate_face_normals()
|
||||||
|
|
||||||
while running:
|
while running:
|
||||||
for event in pygame.event.get():
|
for event in pygame.event.get():
|
||||||
|
|
Loading…
Reference in New Issue