common_rules.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #
  2. # Copyright (c) Contributors to the Open 3D Engine Project.
  3. # For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. #
  5. # SPDX-License-Identifier: Apache-2.0 OR MIT
  6. #
  7. #
  8. import traceback, sys, uuid, os, json, logging
  9. def log_exception_traceback():
  10. """
  11. Outputs an exception stacktrace.
  12. """
  13. data = traceback.format_exc()
  14. logger = logging.getLogger('python')
  15. logger.error(data)
  16. class BaseRule():
  17. """
  18. Base class of the actor rules to help encode the type name of abstract rules
  19. Parameters
  20. ----------
  21. typename : str
  22. A typename the $type will be in the JSON chunk object
  23. Attributes
  24. ----------
  25. typename: str
  26. The type name of the abstract classes to be serialized
  27. id: UUID
  28. a unique ID for the rule
  29. Methods
  30. -------
  31. to_dict()
  32. Converts contents to a Python dictionary
  33. Adds the '$type' member
  34. Adds a random 'id' member
  35. Note: Override this method if a derviced class needs to return a custom dictionary
  36. """
  37. def __init__(self, typename):
  38. self.typename = typename
  39. self.id = uuid.uuid4()
  40. def __eq__(self, other):
  41. return self.id.__eq__(other.id)
  42. def __ne__(self, other):
  43. return self.__eq__(other) is False
  44. def __hash__(self):
  45. return self.id.__hash__()
  46. def to_dict(self):
  47. data = vars(self)
  48. data['id'] = f"{{{str(self.id)}}}"
  49. # rename 'typename' to '$type'
  50. data['$type'] = self.typename
  51. data.pop('typename')
  52. return data
  53. def convert_rule_to_json(rule:BaseRule, indentValue=0):
  54. """
  55. Helper function to convert a BaseRule into a JSON string
  56. Parameters
  57. ----------
  58. obj : any
  59. The object to convert to a JSON string as long as the obj class has an *to_dict* method
  60. indentValue : int
  61. The number of spaces to indent between each JSON block/value
  62. """
  63. return json.dumps(rule.to_dict(), indent=indentValue, cls=RuleEncoder)
  64. class CommentRule(BaseRule):
  65. """
  66. Add an optional comment to the asset's properties.
  67. Attributes
  68. ----------
  69. text: str
  70. Text for the comment.
  71. Methods
  72. -------
  73. to_dict()
  74. Converts contents to a Python dictionary
  75. """
  76. def __init__(self):
  77. super().__init__('CommentRule')
  78. self.text = ''
  79. class SceneNodeSelectionList(BaseRule):
  80. """
  81. Contains a list of node names to include (selectedNodes) and to exclude (unselectedNodes)
  82. Attributes
  83. ----------
  84. selectedNodes: `list` of str
  85. The node names to include for this group rule
  86. unselectedNodes: `list` of str
  87. The node names to exclude for this group rule
  88. Methods
  89. -------
  90. convert_selection(self, container, key):
  91. this adds its contents to an existing dictionary container at a key position
  92. select_targets(self, selectedList, allNodesList:list)
  93. helper function to include a small list of node names from list of all the node names
  94. to_dict()
  95. Converts contents to a Python dictionary
  96. """
  97. def __init__(self):
  98. super().__init__('SceneNodeSelectionList')
  99. self.selectedNodes = []
  100. self.unselectedNodes = []
  101. def convert_selection(self, container, key):
  102. container[key] = self.to_dict()
  103. def select_targets(self, selectedList, allNodesList:list):
  104. self.selectedNodes = selectedList
  105. self.unselectedNodes = allNodesList.copy()
  106. for node in selectedList:
  107. if node in self.unselectedNodes:
  108. self.unselectedNodes.remove(node)
  109. class CoordinateSystemRule(BaseRule):
  110. """
  111. Modify the target coordinate system, applying a transformation to all data (transforms and vertex data if it exists).
  112. Attributes
  113. ----------
  114. targetCoordinateSystem: int
  115. Change the direction the actor/motion will face by applying a post transformation to the data.
  116. useAdvancedData: bool
  117. If True, use advanced settings
  118. originNodeName: str
  119. Select a Node from the scene as the origin for this export.
  120. rotation: [float, float, float, float]
  121. Sets the orientation offset of the processed mesh in degrees. Rotates (yaw, pitch, roll) the group after translation.
  122. translation: [float, float, float]
  123. Moves the group along the given vector3.
  124. scale: float
  125. Sets the scale offset of the processed mesh.
  126. """
  127. def __init__(self):
  128. super().__init__('CoordinateSystemRule')
  129. self.targetCoordinateSystem = 0
  130. self.useAdvancedData = False
  131. self.originNodeName = ''
  132. self.rotation = [0.0, 0.0, 0.0, 1.0]
  133. self.translation = [0.0, 0.0, 0.0]
  134. self.scale = 1.0
  135. class TypeId():
  136. """
  137. Wraps a UUID that represents a AZ::TypeId from O3DE
  138. Attributes
  139. ----------
  140. valud: uuid.Uuid
  141. A unique ID that defaults to AZ::TypeId::CreateNull()
  142. """
  143. def __init__(self):
  144. self.value = uuid.UUID('{00000000-0000-0000-0000-000000000000}')
  145. def __str__(self):
  146. return f"{{{str(self.value)}}}"
  147. class RuleEncoder(json.JSONEncoder):
  148. """
  149. A helper class to encode the Python classes with to a Python dictionary
  150. Methods
  151. -------
  152. default(obj)
  153. Converts a single object to a JSON value that can be stored with a key
  154. encode(obj)
  155. Converts contents to a Python dictionary for the JSONEncoder
  156. """
  157. def default(self, obj):
  158. if (isinstance(obj,TypeId)):
  159. return str(obj)
  160. elif hasattr(obj, 'to_json_value'):
  161. return obj.to_json_value()
  162. return super().default(obj)
  163. def encode(self, obj):
  164. chunk = obj
  165. if isinstance(obj, BaseRule):
  166. chunk = obj.to_dict()
  167. elif isinstance(obj, dict):
  168. chunk = obj
  169. elif hasattr(obj, 'to_dict'):
  170. chunk = obj.to_dict()
  171. else:
  172. chunk = obj.__dict__
  173. return super().encode(chunk)