collada/buffer: correctly handle <mesh> with more than one <triangles>
This commit is contained in:
parent
2a0d4dd20b
commit
02b2f1a95f
@ -1,5 +1,8 @@
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from itertools import chain, islice
|
from itertools import chain, islice
|
||||||
|
from typing import Dict, Tuple, List
|
||||||
|
from dataclasses import dataclass
|
||||||
|
import dataclasses
|
||||||
|
|
||||||
from collada import parse
|
from collada import parse
|
||||||
from collada import types
|
from collada import types
|
||||||
@ -8,7 +11,7 @@ from collada.util import find_semantics
|
|||||||
def linearize_offset_table(by_offset, p_stride):
|
def linearize_offset_table(by_offset, p_stride):
|
||||||
for offset in range(p_stride):
|
for offset in range(p_stride):
|
||||||
for input, source in by_offset[offset]:
|
for input, source in by_offset[offset]:
|
||||||
yield offset, input, source
|
yield input, source
|
||||||
|
|
||||||
mesh_semantic_names = ["NORMAL", "TEXCOORD"]
|
mesh_semantic_names = ["NORMAL", "TEXCOORD"]
|
||||||
|
|
||||||
@ -34,65 +37,85 @@ def build_offset_table(collada, triangles, p_stride):
|
|||||||
linearized_table = linearize_offset_table(by_offset, p_stride)
|
linearized_table = linearize_offset_table(by_offset, p_stride)
|
||||||
return list(linearized_table), used_offsets
|
return list(linearized_table), used_offsets
|
||||||
|
|
||||||
def mesh_vertex_index_buffer(collada, mesh):
|
def mesh_vertex_index_buffer_triangles(collada, mesh, triangles):
|
||||||
assert len(mesh.primitive_elements) == 1
|
|
||||||
triangles, = mesh.primitive_elements
|
|
||||||
assert type(triangles) is types.Triangles
|
|
||||||
|
|
||||||
max_offset = max(i.offset for i in triangles.inputs)
|
max_offset = max(i.offset for i in triangles.inputs)
|
||||||
p_stride = max_offset + 1
|
p_stride = max_offset + 1
|
||||||
offset_table, used_offsets = build_offset_table(collada, triangles, p_stride)
|
offset_table, used_offsets = build_offset_table(collada, triangles, p_stride)
|
||||||
|
|
||||||
######################################################################
|
from prettyprinter import pprint, install_extras
|
||||||
# generate the index and vertex buffers
|
install_extras(include=["dataclasses"])
|
||||||
######################################################################
|
|
||||||
|
|
||||||
vertex_buffer_stride = sum(
|
@dataclass
|
||||||
source.technique_common.accessor.stride
|
class MeshVertexIndexBufferState:
|
||||||
for offset, input, source in offset_table
|
index_buffer: List[int]
|
||||||
)
|
|
||||||
vertex_index_table = []
|
def __init__(self):
|
||||||
|
self.index_buffer = [] # a list of integers
|
||||||
|
self.vertex_buffer = [] # a list of floats
|
||||||
|
|
||||||
|
# vertex_index_table: input/collada vertex indices in the order written
|
||||||
|
# to the index buffer
|
||||||
|
# indices: output vertex index (absolute)
|
||||||
|
# values: collada vertex index
|
||||||
|
self.vertex_index_table = []
|
||||||
|
|
||||||
|
# one offset table per <triangles>
|
||||||
|
self.offset_tables = []
|
||||||
|
|
||||||
|
def mesh_vertex_index_buffer(collada, mesh):
|
||||||
|
state = MeshVertexIndexBufferState()
|
||||||
|
|
||||||
|
# index_table:
|
||||||
|
# keys: index_table_key
|
||||||
|
# values: index integer
|
||||||
index_table = {}
|
index_table = {}
|
||||||
next_output_index = 0
|
next_output_index = 0
|
||||||
index_buffer = []
|
|
||||||
vertex_buffer = []
|
|
||||||
|
|
||||||
for vertex_ix in range(triangles.count * 3):
|
for triangles in mesh.primitive_elements:
|
||||||
index_table_key = tuple(triangles.p[vertex_ix * p_stride + offset] for offset in used_offsets)
|
assert type(triangles) is types.Triangles
|
||||||
if index_table_key in index_table:
|
|
||||||
index_buffer.append(index_table[index_table_key])
|
|
||||||
continue
|
|
||||||
|
|
||||||
index_table[index_table_key] = next_output_index
|
max_offset = max(i.offset for i in triangles.inputs)
|
||||||
index_buffer.append(next_output_index)
|
p_stride = max_offset + 1
|
||||||
next_output_index += 1
|
offset_table, used_offsets = build_offset_table(collada, triangles, p_stride)
|
||||||
|
state.offset_tables.append(offset_table)
|
||||||
|
input_key = tuple(dataclasses.astuple(input) for input, source in offset_table)
|
||||||
|
|
||||||
# emit vertex attributes for new output index in vertex buffer
|
for vertex_ix in range(triangles.count * 3):
|
||||||
for offset, input, source in offset_table:
|
offset_key = tuple(triangles.p[vertex_ix * p_stride + offset] for offset in used_offsets)
|
||||||
p_index = triangles.p[vertex_ix * p_stride + offset]
|
index_table_key = tuple((input_key, offset_key))
|
||||||
if input.semantic == "VERTEX":
|
|
||||||
vertex_index_table.append(p_index)
|
|
||||||
|
|
||||||
source_stride = source.technique_common.accessor.stride
|
######################################################################
|
||||||
source_index = p_index * source_stride
|
# append to the index buffer
|
||||||
array_slice = source.array_element.floats[source_index:source_index+source_stride]
|
######################################################################
|
||||||
vertex_buffer.extend(array_slice)
|
if index_table_key in index_table:
|
||||||
|
state.index_buffer.append(index_table[index_table_key])
|
||||||
|
continue
|
||||||
|
index_table[index_table_key] = next_output_index
|
||||||
|
state.index_buffer.append(next_output_index)
|
||||||
|
next_output_index += 1
|
||||||
|
|
||||||
assert len(index_buffer) == triangles.count * 3
|
######################################################################
|
||||||
assert len(vertex_buffer) == len(index_table) * vertex_buffer_stride
|
# emit vertex attributes for new output index in vertex buffer
|
||||||
|
######################################################################
|
||||||
|
for input, source in offset_table:
|
||||||
|
p_index = triangles.p[vertex_ix * p_stride + input.offset]
|
||||||
|
if input.semantic == "VERTEX":
|
||||||
|
state.vertex_index_table.append(p_index)
|
||||||
|
|
||||||
input_source_table = [(input, source) for offset, input, source in offset_table]
|
source_stride = source.technique_common.accessor.stride
|
||||||
|
source_index = p_index * source_stride
|
||||||
|
assert type(source.array_element) is types.FloatArray
|
||||||
|
array_slice = source.array_element.floats[source_index:source_index+source_stride]
|
||||||
|
state.vertex_buffer.extend(array_slice)
|
||||||
|
|
||||||
# vertex_index_table: input/collada vertex indices in the order written to the index buffer
|
return state
|
||||||
# input_source_table: (input, source) in the order written to the vertex buffer
|
|
||||||
return vertex_buffer, index_buffer, vertex_index_table, input_source_table
|
|
||||||
|
|
||||||
def skin_vertex_buffer(collada, skin, vertex_index_table):
|
def skin_vertex_buffer(collada, skin, vertex_index_table):
|
||||||
max_offset = max(i.offset for i in skin.vertex_weights.inputs)
|
max_offset = max(i.offset for i in skin.vertex_weights.inputs)
|
||||||
weights_input, = find_semantics(skin.vertex_weights.inputs, "WEIGHT")
|
|
||||||
weights_source = collada.lookup(weights_input.source, types.SourceCore)
|
|
||||||
joints_input, = find_semantics(skin.vertex_weights.inputs, "JOINT")
|
joints_input, = find_semantics(skin.vertex_weights.inputs, "JOINT")
|
||||||
joints_source = collada.lookup(joints_input.source, types.SourceCore)
|
joints_source = collada.lookup(joints_input.source, types.SourceCore)
|
||||||
|
weights_input, = find_semantics(skin.vertex_weights.inputs, "WEIGHT")
|
||||||
|
weights_source = collada.lookup(weights_input.source, types.SourceCore)
|
||||||
assert weights_source.technique_common.accessor.stride == 1
|
assert weights_source.technique_common.accessor.stride == 1
|
||||||
assert joints_source.technique_common.accessor.stride == 1
|
assert joints_source.technique_common.accessor.stride == 1
|
||||||
|
|
||||||
@ -136,8 +159,8 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
mesh = collada.library_geometries[0].geometries[0].geometric_element
|
mesh = collada.library_geometries[0].geometries[0].geometric_element
|
||||||
assert type(mesh) is types.Mesh
|
assert type(mesh) is types.Mesh
|
||||||
vertex_buffer_pnt, index_buffer, vertex_index_table, input_source_table = mesh_vertex_index_buffer(collada, mesh)
|
state = mesh_vertex_index_buffer(collada, mesh)
|
||||||
|
|
||||||
skin = collada.library_controllers[0].controllers[0].control_element
|
#skin = collada.library_controllers[0].controllers[0].control_element
|
||||||
assert type(skin) is types.Skin
|
#assert type(skin) is types.Skin
|
||||||
vertex_buffer_jw = skin_vertex_buffer(collada, skin, vertex_index_table)
|
#vertex_buffer_jw = skin_vertex_buffer(collada, skin, vertex_index_table)
|
||||||
|
|||||||
140
collada/types.py
140
collada/types.py
@ -9,14 +9,14 @@ Float3 = Tuple[float, float, float]
|
|||||||
Float4 = Tuple[float, float, float, float]
|
Float4 = Tuple[float, float, float, float]
|
||||||
Float7 = Tuple[float, float, float, float, float, float, float]
|
Float7 = Tuple[float, float, float, float, float, float, float]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Lookat:
|
class Lookat:
|
||||||
sid: Optional[str]
|
sid: Optional[str]
|
||||||
eye: Float3
|
eye: Float3
|
||||||
at: Float3
|
at: Float3
|
||||||
up: Float3
|
up: Float3
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Matrix:
|
class Matrix:
|
||||||
# collada is the transpose of a directx matrix
|
# collada is the transpose of a directx matrix
|
||||||
# 1.0 0.0 0.0 0.0
|
# 1.0 0.0 0.0 0.0
|
||||||
@ -26,35 +26,35 @@ class Matrix:
|
|||||||
sid: Optional[str]
|
sid: Optional[str]
|
||||||
values: Tuple[Float4, Float4, Float4, Float4]
|
values: Tuple[Float4, Float4, Float4, Float4]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Rotate:
|
class Rotate:
|
||||||
# x y z w ; quaternion
|
# x y z w ; quaternion
|
||||||
sid: Optional[str]
|
sid: Optional[str]
|
||||||
rotate: Float4
|
rotate: Float4
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Scale:
|
class Scale:
|
||||||
sid: Optional[str]
|
sid: Optional[str]
|
||||||
scale: Float3
|
scale: Float3
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Skew:
|
class Skew:
|
||||||
sid: Optional[str]
|
sid: Optional[str]
|
||||||
skew: Float7
|
skew: Float7
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Translate:
|
class Translate:
|
||||||
sid: Optional[str]
|
sid: Optional[str]
|
||||||
translate: Float3
|
translate: Float3
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Param:
|
class Param:
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
sid: Optional[str]
|
sid: Optional[str]
|
||||||
type: str
|
type: str
|
||||||
semantic: Optional[str]
|
semantic: Optional[str]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Accessor:
|
class Accessor:
|
||||||
count: int
|
count: int
|
||||||
offset: Optional[int]
|
offset: Optional[int]
|
||||||
@ -65,33 +65,33 @@ class Accessor:
|
|||||||
|
|
||||||
sid_lookup: dict = field(repr=False)
|
sid_lookup: dict = field(repr=False)
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class TechniqueCommon_SourceCore:
|
class TechniqueCommon_SourceCore:
|
||||||
accessor: Accessor
|
accessor: Accessor
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Ambient:
|
class Ambient:
|
||||||
color: Float3
|
color: Float3
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Directional:
|
class Directional:
|
||||||
color: Float3
|
color: Float3
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Point:
|
class Point:
|
||||||
color: Float3
|
color: Float3
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Spot:
|
class Spot:
|
||||||
color: Float3
|
color: Float3
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class BindVertexInput:
|
class BindVertexInput:
|
||||||
semantic: str
|
semantic: str
|
||||||
input_semantic: str
|
input_semantic: str
|
||||||
input_set: int
|
input_set: int
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class InstanceMaterial:
|
class InstanceMaterial:
|
||||||
sid: Optional[str]
|
sid: Optional[str]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
@ -100,17 +100,17 @@ class InstanceMaterial:
|
|||||||
|
|
||||||
bind_vertex_inputs: List[BindVertexInput]
|
bind_vertex_inputs: List[BindVertexInput]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class TechniqueCommon_BindMaterial:
|
class TechniqueCommon_BindMaterial:
|
||||||
materials: List[InstanceMaterial] # one or more
|
materials: List[InstanceMaterial] # one or more
|
||||||
|
|
||||||
sid_lookup: dict = field(repr=False)
|
sid_lookup: dict = field(repr=False)
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class BindMaterial:
|
class BindMaterial:
|
||||||
technique_common: TechniqueCommon_BindMaterial
|
technique_common: TechniqueCommon_BindMaterial
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class InstanceGeometry:
|
class InstanceGeometry:
|
||||||
sid: Optional[str]
|
sid: Optional[str]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
@ -119,19 +119,19 @@ class InstanceGeometry:
|
|||||||
# child element
|
# child element
|
||||||
bind_material: Optional[BindMaterial]
|
bind_material: Optional[BindMaterial]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class InstanceLight:
|
class InstanceLight:
|
||||||
sid: Optional[str]
|
sid: Optional[str]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
url: URI
|
url: URI
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class InstanceVisualScene:
|
class InstanceVisualScene:
|
||||||
sid: Optional[str]
|
sid: Optional[str]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
url: URI
|
url: URI
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Scene:
|
class Scene:
|
||||||
instance_visual_scene: InstanceVisualScene
|
instance_visual_scene: InstanceVisualScene
|
||||||
|
|
||||||
@ -146,43 +146,43 @@ class FxSurfaceType(Enum):
|
|||||||
DEPTH = auto()
|
DEPTH = auto()
|
||||||
RECT = auto()
|
RECT = auto()
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class InitFrom:
|
class InitFrom:
|
||||||
uri: str
|
uri: str
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Surface:
|
class Surface:
|
||||||
type: FxSurfaceType
|
type: FxSurfaceType
|
||||||
|
|
||||||
init_from: InitFrom
|
init_from: InitFrom
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class SourceFX:
|
class SourceFX:
|
||||||
sid: ID
|
sid: ID
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Sampler2D:
|
class Sampler2D:
|
||||||
source: SourceFX
|
source: SourceFX
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Newparam:
|
class Newparam:
|
||||||
sid: str # required
|
sid: str # required
|
||||||
parameter_type: Union[Surface, Sampler2D]
|
parameter_type: Union[Surface, Sampler2D]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Color:
|
class Color:
|
||||||
value: Float4
|
value: Float4
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Float:
|
class Float:
|
||||||
value: float
|
value: float
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Texture:
|
class Texture:
|
||||||
texture: str
|
texture: str
|
||||||
texcoord: str
|
texcoord: str
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Blinn:
|
class Blinn:
|
||||||
emission: Optional[Union[Color, Texture]]
|
emission: Optional[Union[Color, Texture]]
|
||||||
ambient: Optional[Union[Color, Texture]]
|
ambient: Optional[Union[Color, Texture]]
|
||||||
@ -195,7 +195,7 @@ class Blinn:
|
|||||||
transparency: Optional[Float]
|
transparency: Optional[Float]
|
||||||
index_of_refraction: Optional[Float]
|
index_of_refraction: Optional[Float]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Lambert:
|
class Lambert:
|
||||||
emission: Optional[Union[Color, Texture]]
|
emission: Optional[Union[Color, Texture]]
|
||||||
ambient: Optional[Union[Color, Texture]]
|
ambient: Optional[Union[Color, Texture]]
|
||||||
@ -206,7 +206,7 @@ class Lambert:
|
|||||||
transparency: Optional[Float]
|
transparency: Optional[Float]
|
||||||
index_of_refraction: Optional[Float]
|
index_of_refraction: Optional[Float]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Phong:
|
class Phong:
|
||||||
emission: Optional[Union[Color, Texture]]
|
emission: Optional[Union[Color, Texture]]
|
||||||
ambient: Optional[Union[Color, Texture]]
|
ambient: Optional[Union[Color, Texture]]
|
||||||
@ -219,7 +219,7 @@ class Phong:
|
|||||||
transparency: Optional[Float]
|
transparency: Optional[Float]
|
||||||
index_of_refraction: Optional[Float]
|
index_of_refraction: Optional[Float]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Constant:
|
class Constant:
|
||||||
emission: Optional[Color]
|
emission: Optional[Color]
|
||||||
reflective: Optional[Union[Color, Texture]]
|
reflective: Optional[Union[Color, Texture]]
|
||||||
@ -228,13 +228,13 @@ class Constant:
|
|||||||
transparency: Optional[Float]
|
transparency: Optional[Float]
|
||||||
index_of_refraction: Optional[Float]
|
index_of_refraction: Optional[Float]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class TechniqueFX:
|
class TechniqueFX:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
sid: str # required
|
sid: str # required
|
||||||
shader: Union[Blinn, Lambert, Phong, Constant]
|
shader: Union[Blinn, Lambert, Phong, Constant]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class ProfileCommon:
|
class ProfileCommon:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
|
|
||||||
@ -243,27 +243,27 @@ class ProfileCommon:
|
|||||||
|
|
||||||
sid_lookup: dict = field(repr=False)
|
sid_lookup: dict = field(repr=False)
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Effect:
|
class Effect:
|
||||||
id: str
|
id: str
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
|
|
||||||
profile_common: List[ProfileCommon]
|
profile_common: List[ProfileCommon]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class LibraryEffects:
|
class LibraryEffects:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
|
|
||||||
effects: List[Effect]
|
effects: List[Effect]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class InstanceEffect:
|
class InstanceEffect:
|
||||||
sid: Optional[str]
|
sid: Optional[str]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
url: URI
|
url: URI
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Material:
|
class Material:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
@ -272,14 +272,14 @@ class Material:
|
|||||||
|
|
||||||
sid_lookup: dict = field(repr=False)
|
sid_lookup: dict = field(repr=False)
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class LibraryMaterials:
|
class LibraryMaterials:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
|
|
||||||
materials: List[Material]
|
materials: List[Material]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class NameArray:
|
class NameArray:
|
||||||
count: int
|
count: int
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
@ -287,7 +287,7 @@ class NameArray:
|
|||||||
|
|
||||||
names: List[str]
|
names: List[str]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class BoolArray:
|
class BoolArray:
|
||||||
count: int
|
count: int
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
@ -295,7 +295,7 @@ class BoolArray:
|
|||||||
|
|
||||||
bools: List[bool]
|
bools: List[bool]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class FloatArray:
|
class FloatArray:
|
||||||
count: int
|
count: int
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
@ -305,7 +305,7 @@ class FloatArray:
|
|||||||
|
|
||||||
floats: List[float]
|
floats: List[float]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class IntArray:
|
class IntArray:
|
||||||
count: int
|
count: int
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
@ -315,7 +315,7 @@ class IntArray:
|
|||||||
|
|
||||||
ints: List[int]
|
ints: List[int]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class SourceCore:
|
class SourceCore:
|
||||||
id: ID
|
id: ID
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
@ -323,14 +323,14 @@ class SourceCore:
|
|||||||
array_element: Union[NameArray, BoolArray, FloatArray, IntArray]
|
array_element: Union[NameArray, BoolArray, FloatArray, IntArray]
|
||||||
technique_common: TechniqueCommon_SourceCore
|
technique_common: TechniqueCommon_SourceCore
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class InputShared:
|
class InputShared:
|
||||||
offset: int
|
offset: int
|
||||||
semantic: str
|
semantic: str
|
||||||
source: URI
|
source: URI
|
||||||
set: Optional[int]
|
set: Optional[int]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Triangles:
|
class Triangles:
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
count: int
|
count: int
|
||||||
@ -338,57 +338,57 @@ class Triangles:
|
|||||||
inputs: List[InputShared]
|
inputs: List[InputShared]
|
||||||
p: List[int]
|
p: List[int]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class InputUnshared:
|
class InputUnshared:
|
||||||
semantic: str
|
semantic: str
|
||||||
source: URI
|
source: URI
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Vertices:
|
class Vertices:
|
||||||
id: ID
|
id: ID
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
|
|
||||||
inputs: List[InputUnshared] # 1 or more
|
inputs: List[InputUnshared] # 1 or more
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Mesh:
|
class Mesh:
|
||||||
sources: List[SourceCore]
|
sources: List[SourceCore]
|
||||||
vertices: Vertices
|
vertices: Vertices
|
||||||
primitive_elements: List[Union[Triangles]]
|
primitive_elements: List[Union[Triangles]]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Geometry:
|
class Geometry:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
|
|
||||||
geometric_element: Union[Mesh]
|
geometric_element: Union[Mesh]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class LibraryGeometries:
|
class LibraryGeometries:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
|
|
||||||
geometries: List[Geometry]
|
geometries: List[Geometry]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class TechniqueCommon_Light:
|
class TechniqueCommon_Light:
|
||||||
light: Union[Ambient, Directional, Point, Spot]
|
light: Union[Ambient, Directional, Point, Spot]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Light:
|
class Light:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
|
|
||||||
technique_common: TechniqueCommon_Light
|
technique_common: TechniqueCommon_Light
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class LibraryLights:
|
class LibraryLights:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
|
|
||||||
lights: List[Light]
|
lights: List[Light]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Image:
|
class Image:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
@ -399,7 +399,7 @@ class Image:
|
|||||||
|
|
||||||
image_source: Union[InitFrom]
|
image_source: Union[InitFrom]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class LibraryImages:
|
class LibraryImages:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
@ -412,7 +412,7 @@ class NodeType(Enum):
|
|||||||
|
|
||||||
TransformationElements = Union[Lookat, Matrix, Rotate, Scale, Skew, Translate]
|
TransformationElements = Union[Lookat, Matrix, Rotate, Scale, Skew, Translate]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Node:
|
class Node:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
@ -427,7 +427,7 @@ class Node:
|
|||||||
|
|
||||||
sid_lookup: dict = field(repr=False)
|
sid_lookup: dict = field(repr=False)
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class VisualScene:
|
class VisualScene:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
@ -436,30 +436,30 @@ class VisualScene:
|
|||||||
|
|
||||||
sid_lookup: dict = field(repr=False)
|
sid_lookup: dict = field(repr=False)
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class LibraryVisualScenes:
|
class LibraryVisualScenes:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
|
|
||||||
visual_scenes: List[VisualScene]
|
visual_scenes: List[VisualScene]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class BindShapeMatrix:
|
class BindShapeMatrix:
|
||||||
# it is written in row-major order in the COLLADA document for
|
# it is written in row-major order in the COLLADA document for
|
||||||
# human readability.
|
# human readability.
|
||||||
values: Tuple[Float4, Float4, Float4, Float4]
|
values: Tuple[Float4, Float4, Float4, Float4]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Joints:
|
class Joints:
|
||||||
inputs: List[InputUnshared] # 2 or more
|
inputs: List[InputUnshared] # 2 or more
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class VertexWeights:
|
class VertexWeights:
|
||||||
inputs: List[InputShared] # 2 or more
|
inputs: List[InputShared] # 2 or more
|
||||||
vcount: List[int]
|
vcount: List[int]
|
||||||
v: List[int]
|
v: List[int]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Skin:
|
class Skin:
|
||||||
source: URI # required
|
source: URI # required
|
||||||
|
|
||||||
@ -468,31 +468,31 @@ class Skin:
|
|||||||
joints: Joints # 1
|
joints: Joints # 1
|
||||||
vertex_weights: VertexWeights # 1
|
vertex_weights: VertexWeights # 1
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Controller:
|
class Controller:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
|
|
||||||
control_element: Union[Skin]
|
control_element: Union[Skin]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class LibraryControllers:
|
class LibraryControllers:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
|
|
||||||
controllers: List[Controller]
|
controllers: List[Controller]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Sampler:
|
class Sampler:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
inputs: List[InputUnshared] # 1 or more
|
inputs: List[InputUnshared] # 1 or more
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Channel:
|
class Channel:
|
||||||
source: URI
|
source: URI
|
||||||
target: URI
|
target: URI
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class Animation:
|
class Animation:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
@ -502,7 +502,7 @@ class Animation:
|
|||||||
samplers: List[Sampler]
|
samplers: List[Sampler]
|
||||||
channels: List[Channel]
|
channels: List[Channel]
|
||||||
|
|
||||||
@dataclass
|
@dataclass(frozen=True)
|
||||||
class LibraryAnimations:
|
class LibraryAnimations:
|
||||||
id: Optional[ID]
|
id: Optional[ID]
|
||||||
name: Optional[str]
|
name: Optional[str]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user