d3d10/collada/types.py

542 lines
10 KiB
Python

from dataclasses import dataclass, field
from enum import Enum, auto
from typing import Optional, Union, List, Tuple
URI = str
ID = str
Float3 = Tuple[float, float, float]
Float4 = Tuple[float, float, float, float]
Float7 = Tuple[float, float, float, float, float, float, float]
@dataclass
class Lookat:
sid: Optional[str]
eye: Float3
at: Float3
up: Float3
@dataclass
class Matrix:
# collada is the transpose of a directx matrix
# 1.0 0.0 0.0 0.0
# 0.0 1.0 0.0 0.0
# 0.0 0.0 1.0 0.0
# 2.0 3.0 4.0 1.0
sid: Optional[str]
values: Tuple[Float4, Float4, Float4, Float4]
@dataclass
class Rotate:
# x y z w ; quaternion
sid: Optional[str]
rotate: Float4
@dataclass
class Scale:
sid: Optional[str]
scale: Float3
@dataclass
class Skew:
sid: Optional[str]
skew: Float7
@dataclass
class Translate:
sid: Optional[str]
translate: Float3
@dataclass
class Param:
name: Optional[str]
sid: Optional[str]
type: str
semantic: Optional[str]
@dataclass
class Accessor:
count: int
offset: Optional[int]
source: URI
stride: Optional[int]
params: List[Param]
sid_lookup: dict = field(repr=False)
@dataclass
class TechniqueCommon_SourceCore:
accessor: Accessor
@dataclass
class Ambient:
color: Float3
@dataclass
class Directional:
color: Float3
@dataclass
class Point:
color: Float3
@dataclass
class Spot:
color: Float3
@dataclass
class BindVertexInput:
semantic: str
input_semantic: str
input_set: int
@dataclass
class InstanceMaterial:
sid: Optional[str]
name: Optional[str]
target: URI
symbol: str
bind_vertex_inputs: List[BindVertexInput]
@dataclass
class TechniqueCommon_BindMaterial:
materials: List[InstanceMaterial] # one or more
sid_lookup: dict = field(repr=False)
@dataclass
class BindMaterial:
technique_common: TechniqueCommon_BindMaterial
@dataclass
class InstanceGeometry:
sid: Optional[str]
name: Optional[str]
url: URI
# child element
bind_material: Optional[BindMaterial]
@dataclass
class InstanceLight:
sid: Optional[str]
name: Optional[str]
url: URI
@dataclass
class InstanceVisualScene:
sid: Optional[str]
name: Optional[str]
url: URI
@dataclass
class Scene:
instance_visual_scene: InstanceVisualScene
sid_lookup: dict = field(repr=False)
class FxSurfaceType(Enum):
UNTYPED = auto()
_1D = auto()
_2D = auto()
_3D = auto()
CUBE = auto()
DEPTH = auto()
RECT = auto()
@dataclass
class InitFrom:
uri: str
@dataclass
class Surface:
type: FxSurfaceType
init_from: InitFrom
@dataclass
class SourceFX:
sid: ID
@dataclass
class Sampler2D:
source: SourceFX
@dataclass
class Newparam:
sid: str # required
parameter_type: Union[Surface, Sampler2D]
@dataclass
class Color:
value: Float4
@dataclass
class Float:
value: float
@dataclass
class Texture:
texture: str
texcoord: str
@dataclass
class Blinn:
emission: Optional[Union[Color, Texture]]
ambient: Optional[Union[Color, Texture]]
diffuse: Optional[Union[Color, Texture]]
specular: Optional[Union[Color, Texture]]
shininess: Optional[Float]
reflective: Optional[Union[Color, Texture]]
reflectivity: Optional[Float]
transparent: Optional[Union[Color, Texture]]
transparency: Optional[Float]
index_of_refraction: Optional[Float]
@dataclass
class Lambert:
emission: Optional[Union[Color, Texture]]
ambient: Optional[Union[Color, Texture]]
diffuse: Optional[Union[Color, Texture]]
reflective: Optional[Union[Color, Texture]]
reflectivity: Optional[Float]
transparent: Optional[Union[Color, Texture]]
transparency: Optional[Float]
index_of_refraction: Optional[Float]
@dataclass
class Phong:
emission: Optional[Union[Color, Texture]]
ambient: Optional[Union[Color, Texture]]
diffuse: Optional[Union[Color, Texture]]
specular: Optional[Union[Color, Texture]]
shininess: Optional[Float]
reflective: Optional[Union[Color, Texture]]
reflectivity: Optional[Float]
transparent: Optional[Union[Color, Texture]]
transparency: Optional[Float]
index_of_refraction: Optional[Float]
@dataclass
class Constant:
emission: Optional[Color]
reflective: Optional[Union[Color, Texture]]
reflectivity: Optional[Float]
transparent: Optional[Union[Color, Texture]]
transparency: Optional[Float]
index_of_refraction: Optional[Float]
@dataclass
class TechniqueFX:
id: Optional[ID]
sid: str # required
shader: Union[Blinn, Lambert, Phong, Constant]
@dataclass
class ProfileCommon:
id: Optional[ID]
newparam: List[Newparam]
technique: TechniqueFX
sid_lookup: dict = field(repr=False)
@dataclass
class Effect:
id: str
name: Optional[str]
profile_common: List[ProfileCommon]
@dataclass
class LibraryEffects:
id: Optional[ID]
name: Optional[str]
effects: List[Effect]
@dataclass
class InstanceEffect:
sid: Optional[str]
name: Optional[str]
url: URI
@dataclass
class Material:
id: Optional[ID]
name: Optional[str]
instance_effect: InstanceEffect
sid_lookup: dict = field(repr=False)
@dataclass
class LibraryMaterials:
id: Optional[ID]
name: Optional[str]
materials: List[Material]
@dataclass
class NameArray:
count: int
id: Optional[ID]
name: Optional[str]
names: List[str]
@dataclass
class BoolArray:
count: int
id: Optional[ID]
name: Optional[str]
bools: List[bool]
@dataclass
class FloatArray:
count: int
id: Optional[ID]
name: Optional[str]
digits: Optional[int]
magnitude: Optional[int]
floats: List[float]
@dataclass
class IntArray:
count: int
id: Optional[ID]
name: Optional[str]
minInclusive: Optional[int]
maxInclusive: Optional[int]
ints: List[int]
@dataclass
class SourceCore:
id: ID
name: Optional[str]
array_element: Union[NameArray, BoolArray, FloatArray, IntArray]
technique_common: TechniqueCommon_SourceCore
@dataclass
class InputShared:
offset: int
semantic: str
source: URI
set: Optional[int]
@dataclass
class Triangles:
name: Optional[str]
count: int
material: Optional[str]
inputs: List[InputShared]
p: List[int]
@dataclass
class InputUnshared:
semantic: str
source: URI
@dataclass
class Vertices:
id: ID
name: Optional[str]
input: List[InputUnshared] # 1 or more
@dataclass
class Mesh:
sources: List[SourceCore]
vertices: Vertices
primitive_elements: List[Union[Triangles]]
@dataclass
class Geometry:
id: Optional[ID]
name: Optional[str]
geometric_element: Union[Mesh]
@dataclass
class LibraryGeometries:
id: Optional[ID]
name: Optional[str]
geometries: List[Geometry]
@dataclass
class TechniqueCommon_Light:
light: Union[Ambient, Directional, Point, Spot]
@dataclass
class Light:
id: Optional[ID]
name: Optional[str]
technique_common: TechniqueCommon_Light
@dataclass
class LibraryLights:
id: Optional[ID]
name: Optional[str]
lights: List[Light]
@dataclass
class Image:
id: Optional[ID]
name: Optional[str]
format: Optional[str]
height: Optional[int]
width: Optional[int]
depth: Optional[int]
image_source: Union[InitFrom]
@dataclass
class LibraryImages:
id: Optional[ID]
name: Optional[str]
images: List[Image]
class NodeType(Enum):
JOINT = auto()
NODE = auto()
TransformationElements = Union[Lookat, Matrix, Rotate, Scale, Skew, Translate]
@dataclass
class Node:
id: Optional[ID]
name: Optional[str]
sid: Optional[str]
type: NodeType
layer: List[str]
transformation_elements: List[TransformationElements]
instance_geometries: List[InstanceGeometry]
instance_lights: List[InstanceLight]
nodes: List['Node']
sid_lookup: dict = field(repr=False)
@dataclass
class VisualScene:
id: Optional[ID]
name: Optional[str]
nodes: List[Node]
sid_lookup: dict = field(repr=False)
@dataclass
class LibraryVisualScenes:
id: Optional[ID]
name: Optional[str]
visual_scenes: List[VisualScene]
@dataclass
class BindShapeMatrix:
# it is written in row-major order in the COLLADA document for
# human readability.
values: Tuple[Float4, Float4, Float4, Float4]
@dataclass
class Joints:
inputs: List[InputUnshared] # 2 or more
@dataclass
class VertexWeights:
inputs: List[InputShared] # 2 or more
vcount: List[int]
v: List[int]
@dataclass
class Skin:
source: URI # required
bind_shape_matrix: Optional[BindShapeMatrix]
sources: List[SourceCore] # 3 or more
joints: Joints # 1
vertex_weights: VertexWeights # 1
@dataclass
class Controller:
id: Optional[ID]
name: Optional[str]
control_element: Union[Skin]
@dataclass
class LibraryControllers:
id: Optional[ID]
name: Optional[str]
controllers: List[Controller]
@dataclass
class Sampler:
id: Optional[ID]
inputs: List[InputUnshared] # 1 or more
@dataclass
class Channel:
source: URI
target: URI
@dataclass
class Animation:
id: Optional[ID]
name: Optional[str]
animations: List['Animation']
sources: List[SourceCore]
samplers: List[Sampler]
channels: List[Channel]
@dataclass
class LibraryAnimations:
id: Optional[ID]
name: Optional[str]
animations: List[Animation] # 1 or more
@dataclass
class Collada:
library_animations: List[LibraryAnimations]
library_controllers: List[LibraryControllers]
library_effects: List[LibraryEffects]
library_materials: List[LibraryMaterials]
library_geometries: List[LibraryGeometries]
library_lights: List[LibraryLights]
library_images: List[LibraryImages]
library_visual_scenes: List[LibraryVisualScenes]
scenes: List[Scene]
_lookup: dict = field(repr=False)
def __init__(self):
self.library_animations = []
self.library_controllers = []
self.library_effects = []
self.library_materials = []
self.library_geometries = []
self.library_lights = []
self.library_images = []
self.library_visual_scenes = []
self.scenes = []
self._lookup = None
def lookup(self, s):
assert '/' not in s
assert s.startswith("#")
id = s[1:]
return self._lookup[id]