{lyn2265} adding a Python API for MotionGroup rules (#6215)
* {lyn2265} adding a Python API for MotionGroup rules
Signed-off-by: Allen Jackson <23512001+jackalbe@users.noreply.github.com>
* updating the license headers
added more proper example code for motion group
Signed-off-by: Allen Jackson <23512001+jackalbe@users.noreply.github.com>
* updating the actor group to use the common rules module
Signed-off-by: Allen Jackson <23512001+jackalbe@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
#
|
||||
# Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
#
|
||||
#
|
||||
import traceback, sys, uuid, os, json, logging
|
||||
|
||||
def log_exception_traceback():
|
||||
"""
|
||||
Outputs an exception stacktrace.
|
||||
"""
|
||||
data = traceback.format_exc()
|
||||
logger = logging.getLogger('python')
|
||||
logger.error(data)
|
||||
|
||||
|
||||
class BaseRule():
|
||||
"""
|
||||
Base class of the actor rules to help encode the type name of abstract rules
|
||||
|
||||
Parameters
|
||||
----------
|
||||
typename : str
|
||||
A typename the $type will be in the JSON chunk object
|
||||
|
||||
Attributes
|
||||
----------
|
||||
typename: str
|
||||
The type name of the abstract classes to be serialized
|
||||
|
||||
id: UUID
|
||||
a unique ID for the rule
|
||||
|
||||
Methods
|
||||
-------
|
||||
to_dict()
|
||||
Converts contents to a Python dictionary
|
||||
Adds the '$type' member
|
||||
Adds a random 'id' member
|
||||
Note: Override this method if a derviced class needs to return a custom dictionary
|
||||
|
||||
"""
|
||||
def __init__(self, typename):
|
||||
self.typename = typename
|
||||
self.id = uuid.uuid4()
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.id.__eq__(other.id)
|
||||
|
||||
def __ne__(self, other):
|
||||
return self.__eq__(other) is False
|
||||
|
||||
def __hash__(self):
|
||||
return self.id.__hash__()
|
||||
|
||||
def to_dict(self):
|
||||
data = vars(self)
|
||||
data['id'] = f"{{{str(self.id)}}}"
|
||||
# rename 'typename' to '$type'
|
||||
data['$type'] = self.typename
|
||||
data.pop('typename')
|
||||
return data
|
||||
|
||||
def convert_rule_to_json(rule:BaseRule, indentValue=0):
|
||||
"""
|
||||
Helper function to convert a BaseRule into a JSON string
|
||||
|
||||
Parameters
|
||||
----------
|
||||
obj : any
|
||||
The object to convert to a JSON string as long as the obj class has an *to_dict* method
|
||||
|
||||
indentValue : int
|
||||
The number of spaces to indent between each JSON block/value
|
||||
"""
|
||||
return json.dumps(rule.to_dict(), indent=indentValue, cls=RuleEncoder)
|
||||
|
||||
class CommentRule(BaseRule):
|
||||
"""
|
||||
Add an optional comment to the asset's properties.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
text: str
|
||||
Text for the comment.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
to_dict()
|
||||
Converts contents to a Python dictionary
|
||||
"""
|
||||
def __init__(self):
|
||||
super().__init__('CommentRule')
|
||||
self.text = ''
|
||||
|
||||
|
||||
class SceneNodeSelectionList(BaseRule):
|
||||
"""
|
||||
Contains a list of node names to include (selectedNodes) and to exclude (unselectedNodes)
|
||||
|
||||
Attributes
|
||||
----------
|
||||
selectedNodes: `list` of str
|
||||
The node names to include for this group rule
|
||||
|
||||
unselectedNodes: `list` of str
|
||||
The node names to exclude for this group rule
|
||||
|
||||
Methods
|
||||
-------
|
||||
convert_selection(self, container, key):
|
||||
this adds its contents to an existing dictionary container at a key position
|
||||
|
||||
select_targets(self, selectedList, allNodesList:list)
|
||||
helper function to include a small list of node names from list of all the node names
|
||||
|
||||
to_dict()
|
||||
Converts contents to a Python dictionary
|
||||
"""
|
||||
def __init__(self):
|
||||
super().__init__('SceneNodeSelectionList')
|
||||
self.selectedNodes = []
|
||||
self.unselectedNodes = []
|
||||
|
||||
def convert_selection(self, container, key):
|
||||
container[key] = self.to_dict()
|
||||
|
||||
def select_targets(self, selectedList, allNodesList:list):
|
||||
self.selectedNodes = selectedList
|
||||
self.unselectedNodes = allNodesList.copy()
|
||||
for node in selectedList:
|
||||
if node in self.unselectedNodes:
|
||||
self.unselectedNodes.remove(node)
|
||||
|
||||
|
||||
class CoordinateSystemRule(BaseRule):
|
||||
"""
|
||||
Modify the target coordinate system, applying a transformation to all data (transforms and vertex data if it exists).
|
||||
|
||||
Attributes
|
||||
----------
|
||||
targetCoordinateSystem: int
|
||||
Change the direction the actor/motion will face by applying a post transformation to the data.
|
||||
|
||||
useAdvancedData: bool
|
||||
If True, use advanced settings
|
||||
|
||||
originNodeName: str
|
||||
Select a Node from the scene as the origin for this export.
|
||||
|
||||
rotation: [float, float, float, float]
|
||||
Sets the orientation offset of the processed mesh in degrees. Rotates (yaw, pitch, roll) the group after translation.
|
||||
|
||||
translation: [float, float, float]
|
||||
Moves the group along the given vector3.
|
||||
|
||||
scale: float
|
||||
Sets the scale offset of the processed mesh.
|
||||
|
||||
"""
|
||||
def __init__(self):
|
||||
super().__init__('CoordinateSystemRule')
|
||||
self.targetCoordinateSystem = 0
|
||||
self.useAdvancedData = False
|
||||
self.originNodeName = ''
|
||||
self.rotation = [0.0, 0.0, 0.0, 1.0]
|
||||
self.translation = [0.0, 0.0, 0.0]
|
||||
self.scale = 1.0
|
||||
|
||||
class TypeId():
|
||||
"""
|
||||
Wraps a UUID that represents a AZ::TypeId from O3DE
|
||||
|
||||
Attributes
|
||||
----------
|
||||
valud: uuid.Uuid
|
||||
A unique ID that defaults to AZ::TypeId::CreateNull()
|
||||
"""
|
||||
def __init__(self):
|
||||
self.value = uuid.UUID('{00000000-0000-0000-0000-000000000000}')
|
||||
|
||||
def __str__(self):
|
||||
return f"{{{str(self.value)}}}"
|
||||
|
||||
|
||||
class RuleEncoder(json.JSONEncoder):
|
||||
"""
|
||||
A helper class to encode the Python classes with to a Python dictionary
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
default(obj)
|
||||
Converts a single object to a JSON value that can be stored with a key
|
||||
|
||||
encode(obj)
|
||||
Converts contents to a Python dictionary for the JSONEncoder
|
||||
|
||||
"""
|
||||
def default(self, obj):
|
||||
if (isinstance(obj,TypeId)):
|
||||
return str(obj)
|
||||
elif hasattr(obj, 'to_json_value'):
|
||||
return obj.to_json_value()
|
||||
return super().default(obj)
|
||||
|
||||
def encode(self, obj):
|
||||
chunk = obj
|
||||
if isinstance(obj, BaseRule):
|
||||
chunk = obj.to_dict()
|
||||
elif isinstance(obj, dict):
|
||||
chunk = obj
|
||||
elif hasattr(obj, 'to_dict'):
|
||||
chunk = obj.to_dict()
|
||||
else:
|
||||
chunk = obj.__dict__
|
||||
|
||||
return super().encode(chunk)
|
||||
Reference in New Issue
Block a user