class Mesh: def __init__(self, engine, parent, x, y, z, faces): self.Position = Vector(x, y, z) self.Faces = faces self.mode = "faces" self.parent = parent self.engine = engine self.showHitbox = True self.updateFaces() self.updateRadius() self.collider = MeshCollider(self) def updateMesh(self, camera): self.distance = self.Position.pointLen(camera.Position) self.updateFaces() def updateFaces(self): for face in self.Faces: face.updateFace(self, self.engine.camera, self.engine.light) #vykresli vsechny steny, pokud jejich vzdalenost od kamery je mensi #nez vzdalenost domaci Mesh od kamery #face.distance <= (face.distance - self.distance) + self.distance def drawFaces(self, screen, camera): for face in self.Faces: if (face.render and self.mode == "faces"): vertices = [] for vert in face.V: vertices.append(vert.drawVertex(camera)) self.drawFace(screen, face, vertices) if (self.mode == "mesh"): #vykresli oboji A = face.A.drawVertex(camera) B = face.B.drawVertex(camera) C = face.C.drawVertex(camera) self.drawFace(screen, face, A, B, C) #screen.draw([A,B,C], face.distance, (0,0,0), False) #self.drawRadius(screen) def drawFace(self, screen, face, vertices): if (face.actColor != None): screen.draw(vertices, face.distance, face.actColor, True) #screen.draw(vertices, face.distance, face.actColor, False) def checkCollisions(self, parent, v): answer = self.engine.CollideRadius(self, self.radius, self.Position.addVectorReturn(v)) if (answer[0]): v, obj, collide = self.collider.collision(answer[1], v) if (collide): #v = Vector(v.Position.x, v.Position.y, v.Position.z) obj.addForce(Force(v.x/2, v.y/2, v.z/2)) newForce = self.createBounce(v, obj, 0.5) else: newForce = Force(0,0,0) return collide, v, newForce if (answer[0]): #koliduje, ale nema zastavit objekt pass else: return False, v def createBounce(self, v, component, slow): deltaX = abs(component.Position.x - self.Position.x) deltaY = abs(component.Position.y - self.Position.y) deltaZ = abs(component.Position.z - self.Position.z) if (deltaX >= deltaY and deltaX >= deltaZ): return Force(v.x*-slow, v.y*slow, v.z*slow, slow) if (deltaY >= deltaX and deltaY >= deltaZ): return Force(v.x*slow, v.y*-slow, v.z*slow, slow) if (deltaZ >= deltaX and deltaZ >= deltaY): return Force(v.x*slow, v.y*slow, v.z*-slow, slow) #najde nejvzdalensejsi bod meshe a spocte jeho vzdalenost od stredu #najde polomer hitBoxu def updateRadius(self): self.radius = 0 for face in self.Faces: for vector in face.v: newRadius = vector.length() if (newRadius > self.radius): self.radius = newRadius def changeColor(self, color): for face in self.Faces: face.color = color #metoda, ktera prenacte steny def setFaces(self, faces): self.Faces = faces def drawRadius(self, screen): step = 40 for i in range(0, 360, step): radian = i*math.pi/180 x1 = self.Position.x + self.radius*math.sin(radian) y1 = self.Position.y + self.radius*math.cos(radian) radian = (i+step)*math.pi/180 x2 = self.Position.x + self.radius*math.sin(radian) y2 = self.Position.y + self.radius*math.cos(radian) a1 = Vertex(x1,y1,self.Position.z) a2 = Vertex(x2,y2,self.Position.z) edge = Edge(self.engine, a1, a2).drawEdge(screen) for i in range(0, 360, step): radian = i*math.pi/180 z1 = self.Position.z + self.radius*math.sin(radian) y1 = self.Position.y + self.radius*math.cos(radian) radian = (i+step)*math.pi/180 z2 = self.Position.z + self.radius*math.sin(radian) y2 = self.Position.y + self.radius*math.cos(radian) a1 = Vertex(self.Position.x,y1,z1) a2 = Vertex(self.Position.x,y2,z2) edge = Edge(self.engine, a1, a2).drawEdge(screen) for i in range(0, 360, step): radian = i*math.pi/180 x1 = self.Position.x + self.radius*math.sin(radian) z1 = self.Position.z + self.radius*math.cos(radian) radian = (i+step)*math.pi/180 x2 = self.Position.x + self.radius*math.sin(radian) z2 = self.Position.z + self.radius*math.cos(radian) a1 = Vertex(x1,self.Position.y,z1) a2 = Vertex(x2,self.Position.y,z2) edge = Edge(self.engine, a1, a2).drawEdge(screen)
class Object3D(Component): def __init__(self, engine, x, y, z, mesh=None, rigidBody=False): Component.__init__(self, engine, mesh, rigidBody) self.Position = Vector(x, y, z) self.rigidBody = rigidBody self.v = Vector(0, 0, 0) #pohybovy vektor telesa self.t = 0 self.deltaTime = 0 self.forces = [] self.solid = True self.screen = None def Update(self): keys = pygame.key.get_pressed() if (keys[K_l]): self.addForce(Force(0.1, 0.1, 0)) if (keys[K_j]): self.addForce(Force(-0.1, 0.1, 0)) if (keys[K_k]): self.addForce(Force(0, 1, 0)) self.t = 0 self.physics() #self.mesh.Position.speak("mesh: ") #self.Position.speak("object: ") self.mesh.Position = self.Position #self.v.speak("smerovy vektor: ") def Draw(self, screen): end = self.Position.addVectorReturn(self.v) edge = Edge(self.engine, Vertex(self.Position.x, self.Position.y, self.Position.z), Vertex(end.x, end.y, end.z)) #edge.drawEdge(screen) def physics(self): if (self.rigidBody): self.deltaTime = time.time() - self.engine.oldTime self.v = Vector(0, 0, 0) self.applyForces() self.checkCollisions() self.gravity() self.Position.addVector(self.v) #print(len(self.forces)) #self.v.speak("smer: ") def gravity(self): self.t += self.deltaTime #self.v.y -= 0.981*self.t #self.v.y -= self.t answer = self.mesh.checkCollisions(self, Vector(0, -self.t, 0)) if (not answer[0] and self.v.y <= 0): self.v.y -= self.t else: self.t = 0 def applyForces(self): for force in self.forces: add = force.update(self.deltaTime) if (add.length() > 0): self.v.addVector(add) else: self.removeForce(force) def addForce(self, force): self.forces.append(force) def removeForce(self, force): self.forces.remove(force) def removeAllForces(self): while (len(self.forces) > 0): self.removeForce(self.forces[0]) self.t = 0 def checkCollisions(self): if (self.mesh != None): answer = self.mesh.checkCollisions(self, self.v) self.v = answer[1] if (self.Position.y <= -100): self.t = 0 self.Position.y = -10 if (answer[0]): self.removeAllForces() self.addForce(answer[2])