motion_group.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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. from enum import Enum
  9. import scene_api.common_rules
  10. class MotionGroup(scene_api.common_rules.BaseRule):
  11. """
  12. Configure animation data for exporting.
  13. Attributes
  14. ----------
  15. name: str
  16. Name for the group.
  17. This name will also be used as the name for the generated file.
  18. selectedRootBone: str
  19. The root bone of the animation that will be exported.
  20. rules: list of BaseRule
  21. Add or remove rules to fine-tune the export process.
  22. List of rules for a motion group including:
  23. MotionScaleRule
  24. CoordinateSystemRule
  25. MotionRangeRule
  26. MotionAdditiveRule
  27. MotionSamplingRule
  28. """
  29. def __init__(self):
  30. super().__init__('MotionGroup')
  31. self.name = ''
  32. self.selectedRootBone = ''
  33. self.rules = set()
  34. def add_rule(self, rule) -> bool:
  35. if (rule not in self.rules):
  36. self.rules.add(rule)
  37. return True
  38. return False
  39. def create_rule(self, rule) -> any:
  40. if (self.add_rule(rule)):
  41. return rule
  42. return None
  43. def remove_rule(self, type) -> None:
  44. self.rules.discard(rule)
  45. def to_dict(self) -> dict:
  46. out = super().to_dict()
  47. out['name'] = self.name
  48. out['selectedRootBone'] = self.selectedRootBone
  49. # convert the rules
  50. ruleList = []
  51. for rule in self.rules:
  52. ruleList.append(rule.to_dict())
  53. out['rules'] = ruleList
  54. return out
  55. def to_json(self) -> str:
  56. jsonDOM = self.to_dict()
  57. return json.dumps(jsonDOM, cls=RuleEncoder)
  58. class MotionCompressionSettingsRule(scene_api.common_rules.BaseRule):
  59. """
  60. A BaseRule that ses the error tolerance settings while compressing the animation
  61. Attributes
  62. ----------
  63. maxTranslationError: float
  64. Maximum error allowed in translation.
  65. Min 0.0, Max 0.1
  66. maxRotationError: float
  67. Maximum error allowed in rotation.
  68. Min 0.0, Max 0.1
  69. maxScaleError: float
  70. Maximum error allowed in scale.
  71. Min 0.0, Max 0.01
  72. """
  73. def __init__(self):
  74. super().__init__('MotionCompressionSettingsRule')
  75. self.maxTranslationError = 0.0001
  76. self.maxRotationError = 0.0001
  77. self.maxScaleError = 0.0001
  78. class MotionScaleRule(scene_api.common_rules.BaseRule):
  79. """
  80. A BaseRule that scales the spatial extent of motion
  81. Attributes
  82. ----------
  83. scaleFactor: float
  84. Scale factor; min 0.0001, max 10000.0
  85. """
  86. def __init__(self):
  87. super().__init__('MotionScaleRule')
  88. self.scaleFactor = 1.0
  89. class MotionRangeRule(scene_api.common_rules.BaseRule):
  90. """
  91. A BaseRule that defines the range of the motion that will be exported.
  92. Attributes
  93. ----------
  94. startFrame: float
  95. The start frame of the animation that will be exported.
  96. endFrame: float
  97. The end frame of the animation that will be exported.
  98. """
  99. def __init__(self):
  100. super().__init__('MotionRangeRule')
  101. self.startFrame = 0
  102. self.endFrame = 0
  103. class MotionAdditiveRule(scene_api.common_rules.BaseRule):
  104. """
  105. A BaseRule that makes the motion an additive motion.
  106. Attributes
  107. ----------
  108. sampleFrame: int
  109. The frame number that the motion will be made relative to.
  110. """
  111. def __init__(self):
  112. super().__init__('MotionAdditiveRule')
  113. self.sampleFrame = 0
  114. class SampleRateMethod(Enum):
  115. """
  116. A collection of settings related to sampling of the motion
  117. Attributes
  118. ----------
  119. FromSourceScene: int, value = 0
  120. Use the source scene's sample rate
  121. Custom: int, value = 1
  122. Use the use a custom sample rate
  123. """
  124. FromSourceScene = 0
  125. Custom = 1
  126. def to_json_value(self):
  127. if(self == SampleRateMethod.FromSourceScene):
  128. return 0
  129. return 1
  130. class MotionSamplingRule(scene_api.common_rules.BaseRule):
  131. """
  132. A collection of settings related to sampling of the motion
  133. Attributes
  134. ----------
  135. motionDataType: scene_api.common_rules.TypeId()
  136. The motion data type to use. This defines how the motion data is stored.
  137. This can have an effect on performance and memory usage.
  138. sampleRateMethod: SampleRateMethod
  139. Either use the sample rate from the source scene file or use a custom sample rate.
  140. The sample rate is automatically limited to the rate from source scene file (e.g. FBX)
  141. customSampleRate: float
  142. Overwrite the sample rate of the motion, in frames per second.
  143. Min: 1.0, Max 240.0
  144. translationQualityPercentage: float
  145. The percentage of quality for translation. Higher values preserve quality, but increase memory usage.
  146. Min: 1.0, Max 100.0
  147. rotationQualityPercentage: float
  148. The percentage of quality for rotation. Higher values preserve quality, but increase memory usage.
  149. Min: 1.0, Max 100.0
  150. scaleQualityPercentage: float
  151. The percentage of quality for scale. Higher values preserve quality, but increase memory usage.
  152. Min: 1.0, Max 100.0
  153. allowedSizePercentage: float
  154. The percentage of extra memory usage allowed compared to the smallest size.
  155. For example a value of 10 means we are allowed 10 percent more memory worst case, in trade for extra performance.
  156. Allow 15 percent larger size, in trade for performance (in Automatic mode, so when m_motionDataType is a Null typeId).
  157. Min: 0.0, Max 100.0
  158. keepDuration: bool
  159. When enabled this keep the duration the same as the Fbx motion duration, even if no joints are animated.
  160. When this option is disabled and the motion doesn't animate any joints then the resulting motion will have a duration of zero seconds.
  161. """
  162. def __init__(self):
  163. super().__init__('MotionSamplingRule')
  164. self.motionDataType = scene_api.common_rules.TypeId()
  165. self.sampleRateMethod = SampleRateMethod.FromSourceScene
  166. self.customSampleRate = 60.0
  167. self.translationQualityPercentage = 75.0
  168. self.rotationQualityPercentage = 75.0
  169. self.scaleQualityPercentage = 75.0
  170. self.allowedSizePercentage = 15.0
  171. self.keepDuration = True