You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Gems/PythonAssetBuilder/Editor/Scripts/scene_api/common_rules.py

222 lines
5.9 KiB
Python

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