avatar.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. from .naf import NAF
  2. from .utils import typed_dataclass, field, Vector3, Rotation
  3. from enum import Enum
  4. class AvatarType(Enum):
  5. SKINNABLE = "skinnable"
  6. GLTF = "gltf"
  7. IMAGE = "image"
  8. VIDEO = "video"
  9. AUDIO = "audio"
  10. MODEL = "model"
  11. TEXT = "text"
  12. LIGHT = "light"
  13. PARTICLE = "particle"
  14. PRIMITIVE = "primitive"
  15. UNKNOWN = "unknown"
  16. class HandPose(Enum):
  17. allOpen = 0
  18. thumbDown = 1
  19. indexDown = 2
  20. mrpDown = 3
  21. thumbsUp = 4
  22. point = 5
  23. allGrip = 6
  24. pinch = 7
  25. @typed_dataclass
  26. class Transform:
  27. position: Vector3 = field(default_factory=lambda: Vector3(0, 0, 0))
  28. rotation: Rotation = field(default_factory=lambda: Rotation(0, 0, 0))
  29. scale: Vector3 = field(default_factory=lambda: Vector3(1, 1, 1))
  30. @typed_dataclass
  31. class HandTransform(Transform):
  32. pose: HandPose = HandPose.allOpen
  33. visible: bool = False
  34. @typed_dataclass
  35. class Avatar(NAF):
  36. avatar_url: str = ""
  37. position: Vector3 = field(default_factory=Vector3)
  38. rotation: Rotation = field(default_factory=Rotation)
  39. scale: Vector3 = field(default_factory=lambda: Vector3(1, 1, 1))
  40. template: str = "#remote-avatar"
  41. avatar_type: AvatarType = AvatarType.SKINNABLE
  42. muted: bool = True
  43. sharing_avatar_camera: bool = False
  44. lefthand: HandTransform = field(default_factory=HandTransform)
  45. righthand: HandTransform = field(default_factory=HandTransform)
  46. head_transform: Transform = field(default_factory=lambda: Transform(position=Vector3(0, 1.6, 0)))
  47. @property
  48. def components(self) -> list:
  49. return [
  50. self.position.to_obj(),
  51. self.rotation.to_obj(),
  52. self.scale.to_obj(),
  53. {
  54. "avatarSrc": self.avatar_url,
  55. "avatarType": self.avatar_type.value,
  56. "muted": self.muted,
  57. "isSharingAvatarCamera": self.sharing_avatar_camera,
  58. },
  59. {"left_hand_pose": self.lefthand.pose.value, "right_hand_pose": self.righthand.pose.value},
  60. self.head_transform.position.to_obj(),
  61. self.head_transform.rotation.to_obj(),
  62. self.lefthand.position.to_obj(),
  63. self.lefthand.rotation.to_obj(),
  64. self.lefthand.visible,
  65. self.righthand.position.to_obj(),
  66. self.righthand.rotation.to_obj(),
  67. self.righthand.visible,
  68. ]
  69. @components.setter
  70. def components(self, value):
  71. if value == [] or value is None:
  72. return
  73. (
  74. self.position,
  75. self.rotation,
  76. self.scale,
  77. avatarinfo,
  78. handposes,
  79. self.head_transform.position,
  80. self.head_transform.rotation,
  81. self.lefthand.position,
  82. self.lefthand.rotation,
  83. self.lefthand.visible,
  84. self.righthand.position,
  85. self.righthand.rotation,
  86. self.righthand.visible,
  87. ) = value
  88. self.avatar_url = avatarinfo["avatarSrc"]
  89. self.avatar_type = avatarinfo["avatarType"]
  90. self.muted = avatarinfo["muted"]
  91. self.sharing_avatar_camera = avatarinfo["isSharingAvatarCamera"]
  92. self.lefthand.pose = handposes["left_hand_pose"]
  93. self.righthand.pose = handposes["right_hand_pose"]