[1198] | 1 | import glm
|
---|
| 2 | from typing import List, Tuple
|
---|
| 3 |
|
---|
| 4 | class Creature:
|
---|
| 5 | def __init__(self, group: int, index: int) -> None:
|
---|
| 6 | self.mechParts = []
|
---|
| 7 | self.joints = []
|
---|
| 8 | self.neurons: List[Tuple(int, int)] = []
|
---|
| 9 | self.colorsJoint: List[glm.vec3] = []
|
---|
| 10 | self.colorsPart: List[glm.vec3] = []
|
---|
| 11 | self.stylePart: List[str] = []
|
---|
| 12 | self.styleJoint: List[str] = []
|
---|
| 13 | self.styleNeuron: List[str] = []
|
---|
| 14 | self.partOrient: List[glm.mat4] = []
|
---|
| 15 | self.neuronRelativeOrient: List[glm.mat3] = []
|
---|
| 16 | self.group: int = group
|
---|
| 17 | self.index: int = index
|
---|
| 18 |
|
---|
| 19 | def jointTranslation(self, index: int):
|
---|
| 20 | p1 = glm.vec3(self.mechParts[self.joints[index][0]])
|
---|
| 21 | return p1
|
---|
| 22 |
|
---|
| 23 | def jointLength(self, index: int):
|
---|
| 24 | p1 = glm.vec3(self.mechParts[self.joints[index][0]])
|
---|
| 25 | p2 = glm.vec3(self.mechParts[self.joints[index][1]])
|
---|
| 26 | return glm.length(p2 - p1)
|
---|
| 27 |
|
---|
| 28 | def jointRotation(self, index: int) -> glm.mat4:
|
---|
| 29 | p1 = glm.vec3(self.mechParts[self.joints[index][0]])
|
---|
| 30 | p2 = glm.vec3(self.mechParts[self.joints[index][1]])
|
---|
| 31 |
|
---|
| 32 | z_axis = None
|
---|
| 33 | along_d = p2 - p1
|
---|
| 34 | along_o = self._lookAt(along_d)
|
---|
| 35 | along_z = self._revTransform(*along_o, self.partOrient[self.joints[index][1]][2])
|
---|
| 36 |
|
---|
| 37 | if along_z.y * along_z.y + along_z.z * along_z.z > 0.5*0.5:
|
---|
| 38 | z_axis = glm.vec3(self.partOrient[self.joints[index][1]][2])
|
---|
| 39 | else:
|
---|
| 40 | z_axis = glm.vec3(self.partOrient[self.joints[index][1]][1])
|
---|
| 41 | orient = self._lookAt2(along_d, z_axis)
|
---|
| 42 | return glm.mat4(glm.mat3(*orient))
|
---|
| 43 |
|
---|
| 44 | def partTranslation(self, index: int):
|
---|
| 45 | return glm.vec3(self.mechParts[index])
|
---|
| 46 |
|
---|
| 47 | def partRotationMatrix(self, index: int):
|
---|
| 48 | return self.partOrient[index]
|
---|
| 49 |
|
---|
| 50 | def _lookAt(self, X: glm.vec3) -> Tuple[glm.vec3, glm.vec3, glm.vec3]:
|
---|
| 51 | x = glm.normalize(X)
|
---|
| 52 |
|
---|
| 53 | ax = abs(x.x)
|
---|
| 54 | ay = abs(x.y)
|
---|
| 55 | az = abs(x.z)
|
---|
| 56 | if (ax <= ay) and (ax <= az):
|
---|
| 57 | y = glm.vec3(0, -x.z, x.y)
|
---|
| 58 | elif (ay <= ax) and (ay <= az):
|
---|
| 59 | y = glm.vec3(-x.z, 0, x.x)
|
---|
| 60 | else:
|
---|
| 61 | y = glm.vec3(-x.y, x.x, 0)
|
---|
| 62 | y = glm.normalize(y)
|
---|
| 63 | z = glm.cross(x, y)
|
---|
| 64 | return x, y, z
|
---|
| 65 |
|
---|
| 66 | def _lookAt2(self, X: glm.vec3, d: glm.vec3) -> Tuple[glm.vec3, glm.vec3, glm.vec3]:
|
---|
| 67 | x = glm.normalize(X)
|
---|
| 68 | y = glm.cross(d, x)
|
---|
| 69 | z = glm.cross(x, y)
|
---|
| 70 | if glm.length(y) < 1e-50 or glm.length(z) < 1e-50:
|
---|
| 71 | return self._lookAt(X)
|
---|
| 72 |
|
---|
| 73 | y = glm.normalize(y)
|
---|
| 74 | z = glm.normalize(z)
|
---|
| 75 | return x, y, z
|
---|
| 76 |
|
---|
| 77 | def _revTransform(self, x: glm.vec3, y: glm.vec3, z: glm.vec3, s: glm.vec3) -> glm.vec3:
|
---|
| 78 | return glm.vec3(
|
---|
| 79 | s.x * x.x + s.y * x.y + s.z * x.z,
|
---|
| 80 | s.x * y.x + s.y * y.y + s.z * y.z,
|
---|
| 81 | s.x * z.x + s.y * z.y + s.z * z.z
|
---|
| 82 | ) |
---|