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 | ) |
---|