x/gen: implement all generator functions
This commit is contained in:
parent
ec11cc49d3
commit
2f6aea9c3b
270
x/gen.py
270
x/gen.py
@ -18,15 +18,38 @@ def obj_value(obj):
|
|||||||
def obj_type(obj):
|
def obj_type(obj):
|
||||||
return type(obj_value(obj))
|
return type(obj_value(obj))
|
||||||
|
|
||||||
|
visitors = None
|
||||||
|
def visit(func, obj):
|
||||||
|
global visitors
|
||||||
|
yield from visitors[obj_type(obj)](func, obj)
|
||||||
|
|
||||||
|
def visit_none(func, obj):
|
||||||
|
return
|
||||||
|
yield # empty generator
|
||||||
|
|
||||||
def visit_objects(func, obj):
|
def visit_objects(func, obj):
|
||||||
print("vo", func)
|
yield from func(obj)
|
||||||
yield func(obj)
|
|
||||||
for o in obj_value(obj).objects:
|
for o in obj_value(obj).objects:
|
||||||
yield func(o)
|
yield from visit(func, o)
|
||||||
|
|
||||||
def visit_self(func, obj):
|
def visit_self(func, obj):
|
||||||
print("vs", func)
|
yield from func(obj)
|
||||||
yield func(obj)
|
|
||||||
|
tagged = {
|
||||||
|
templates.Header,
|
||||||
|
templates.Material,
|
||||||
|
templates.TextureFilename,
|
||||||
|
templates.Frame,
|
||||||
|
templates.FrameTransformMatrix,
|
||||||
|
templates.Mesh,
|
||||||
|
templates.MeshMaterialList,
|
||||||
|
templates.MeshNormals,
|
||||||
|
templates.MeshTextureCoords,
|
||||||
|
templates.AnimationKey,
|
||||||
|
templates.AnimationOptions,
|
||||||
|
templates.Animation,
|
||||||
|
templates.AnimationSet,
|
||||||
|
}
|
||||||
|
|
||||||
visitors = {
|
visitors = {
|
||||||
templates.ColorRGBA : visit_self,
|
templates.ColorRGBA : visit_self,
|
||||||
@ -35,7 +58,7 @@ visitors = {
|
|||||||
templates.Vector : visit_self,
|
templates.Vector : visit_self,
|
||||||
templates.MeshFace : visit_self,
|
templates.MeshFace : visit_self,
|
||||||
templates.Coords2D : visit_self,
|
templates.Coords2D : visit_self,
|
||||||
templates.Reference : visit_self,
|
templates.Reference : visit_none,
|
||||||
templates.FloatKeys : visit_self,
|
templates.FloatKeys : visit_self,
|
||||||
templates.TimedFloatKeys : visit_self,
|
templates.TimedFloatKeys : visit_self,
|
||||||
|
|
||||||
@ -80,75 +103,209 @@ type_map = {
|
|||||||
templates.AnimationSet : "animation_set",
|
templates.AnimationSet : "animation_set",
|
||||||
}
|
}
|
||||||
|
|
||||||
type_counter = Counter()
|
|
||||||
def name_gen(obj):
|
|
||||||
global type_counter
|
|
||||||
assert type(obj) is not tuple
|
|
||||||
i = type_counter[type(obj)]
|
|
||||||
type_counter[type(obj)] += 1
|
|
||||||
return i
|
|
||||||
|
|
||||||
name_map = {}
|
name_map = {}
|
||||||
|
obj_map = {}
|
||||||
def add_name_map(obj):
|
def add_name_map(obj):
|
||||||
if type(obj) is not tuple:
|
if type(obj) is not tuple:
|
||||||
return
|
return
|
||||||
|
|
||||||
name, obj = obj
|
name, obj = obj
|
||||||
assert name not in name_map, name
|
assert name not in name_map, name
|
||||||
name_map[name] = obj
|
name_map[id(obj)] = name.decode("utf-8")
|
||||||
|
obj_map[name] = obj
|
||||||
yield None
|
yield None
|
||||||
|
|
||||||
def type_declaration(obj):
|
type_counter = Counter()
|
||||||
|
obj_names = {}
|
||||||
|
def name_gen(obj):
|
||||||
|
global type_counter
|
||||||
|
global obj_names
|
||||||
|
|
||||||
|
assert type(obj) is not tuple
|
||||||
|
|
||||||
|
if id(obj) in name_map:
|
||||||
|
return name_map[id(obj)]
|
||||||
|
elif id(obj) in obj_names:
|
||||||
|
return obj_names[id(obj)]
|
||||||
|
else:
|
||||||
|
i = type_counter[obj_type(obj)]
|
||||||
|
type_counter[obj_type(obj)] += 1
|
||||||
|
obj_names[id(obj)] = i
|
||||||
|
return i
|
||||||
|
|
||||||
|
def get_obj_name(obj):
|
||||||
type_name = type_map[obj_type(obj)]
|
type_name = type_map[obj_type(obj)]
|
||||||
if type(obj) is tuple:
|
if type(obj) is tuple:
|
||||||
name, _ = obj
|
name, _ = obj
|
||||||
string_name = name.decode('utf-8')
|
string_name = name.decode('utf-8')
|
||||||
else:
|
else:
|
||||||
string_name = name_gen(obj)
|
string_name = name_gen(obj)
|
||||||
return f"const {type_name} {type_name}_{string_name}"
|
return f"{type_name}_{string_name}"
|
||||||
|
|
||||||
def generate_predeclaration(obj):
|
def type_declaration(obj):
|
||||||
if type(obj) is not tuple:
|
type_name = type_map[obj_type(obj)]
|
||||||
return
|
string_name = get_obj_name(obj)
|
||||||
|
return f"const {type_name} {string_name}"
|
||||||
|
|
||||||
yield f"{type_declaration(obj)};"
|
def generate_vec3(name, name2, vertices):
|
||||||
|
yield f"vec3 {name}_{name2}[] = {{"
|
||||||
def generate_header(obj):
|
for v in vertices:
|
||||||
yield f"{type_declaration(obj)} {{"
|
coordinates = f"{v.x}, {v.y}, {v.z}"
|
||||||
|
yield f"{{{coordinates}}},"
|
||||||
yield "};"
|
yield "};"
|
||||||
|
|
||||||
def generate_definition(obj):
|
def generate_faces(name, faces):
|
||||||
if obj_type(obj) is templates.Header:
|
yield f"struct mesh_face {name}_faces[] = {{"
|
||||||
yield from generate_header(obj)
|
for f in faces:
|
||||||
elif obj_type(obj) is templates.Material:
|
assert f.nFaceVertexIndices == 3
|
||||||
yield from generate_material(obj)
|
indices = f"{', '.join(map(str, f.faceVertexIndices))}"
|
||||||
elif obj_type(obj) is templates.TextureFilename:
|
yield f"{{{indices}}},"
|
||||||
yield from generate_texture_filename(obj)
|
yield "};"
|
||||||
elif obj_type(obj) is templates.Frame:
|
|
||||||
yield from generate_frame(obj)
|
|
||||||
elif obj_type(obj) is templates.FrameTransformMatrix:
|
|
||||||
yield from generate_frame_transform_matrix(obj)
|
|
||||||
elif obj_type(obj) is templates.Mesh:
|
|
||||||
yield from generate_mesh(obj)
|
|
||||||
elif obj_type(obj) is templates.MeshMaterialList:
|
|
||||||
yield from generate_mesh_material_list(obj)
|
|
||||||
elif obj_type(obj) is templates.MeshNormals:
|
|
||||||
yield from generate_mesh_normals(obj)
|
|
||||||
elif obj_type(obj) is templates.MeshTextureCoords:
|
|
||||||
yield from generate_mesh_texture_coords(obj)
|
|
||||||
elif obj_type(obj) is templates.AnimationKey:
|
|
||||||
yield from generate_animation_key(obj)
|
|
||||||
elif obj_type(obj) is templates.AnimationOptions:
|
|
||||||
yield from generate_animation_options(obj)
|
|
||||||
elif obj_type(obj) is templates.Animation:
|
|
||||||
yield from generate_animation(obj)
|
|
||||||
elif obj_type(obj) is templates.AnimationSet:
|
|
||||||
yield from generate_animation_set(obj)
|
|
||||||
else:
|
|
||||||
assert False, (type(obj), obj)
|
|
||||||
|
|
||||||
def visit(func, obj):
|
def generate_face_indices(name, face_indices):
|
||||||
yield from visitors[obj_type(obj)](func, obj)
|
yield f"int {name}_face_indices[] = {{"
|
||||||
|
for i in face_indices:
|
||||||
|
yield f"{i},"
|
||||||
|
yield "};"
|
||||||
|
|
||||||
|
def generate_predeclaration(obj):
|
||||||
|
name = get_obj_name(obj)
|
||||||
|
if obj_type(obj) is templates.Mesh:
|
||||||
|
yield from generate_vec3(name, "vertices", obj_value(obj).vertices)
|
||||||
|
yield from generate_faces(name, obj_value(obj).faces)
|
||||||
|
elif obj_type(obj) is templates.MeshMaterialList:
|
||||||
|
yield from generate_face_indices(name, obj_value(obj).faceIndices)
|
||||||
|
elif obj_type(obj) is templates.MeshNormals:
|
||||||
|
yield from generate_vec3(name, "normals", obj_value(obj).normals)
|
||||||
|
|
||||||
|
yield f"extern {type_declaration(obj)};"
|
||||||
|
|
||||||
|
def generate_header(obj):
|
||||||
|
yield f".major = {obj.major},"
|
||||||
|
yield f".minor = {obj.minor},"
|
||||||
|
yield f".flags = {obj.flags},"
|
||||||
|
|
||||||
|
def generate_material(obj):
|
||||||
|
face_color = f"{obj.faceColor.r}f, {obj.faceColor.g}f, {obj.faceColor.b}f, {obj.faceColor.a}f"
|
||||||
|
specular_color = f"{obj.specularColor.r}f, {obj.specularColor.g}f, {obj.specularColor.b}f"
|
||||||
|
emissive_color = f"{obj.emissiveColor.r}f, {obj.emissiveColor.g}f, {obj.emissiveColor.b}f"
|
||||||
|
yield f".face_color = {{{face_color}}},"
|
||||||
|
yield f".power = {obj.power}f,"
|
||||||
|
yield f".specular_color = {{{specular_color}}},"
|
||||||
|
yield f".emissive_color = {{{emissive_color}}},"
|
||||||
|
|
||||||
|
def generate_texture_filename(obj):
|
||||||
|
yield ""
|
||||||
|
|
||||||
|
def generate_frame(obj):
|
||||||
|
return
|
||||||
|
yield # empty generator function
|
||||||
|
|
||||||
|
def generate_frame_transform_matrix(obj):
|
||||||
|
yield ".frame_matrix = {"
|
||||||
|
m = obj.frameMatrix.v
|
||||||
|
# transpose matrix from column-major to row-major
|
||||||
|
yield f"{m[0]}, {m[4]}, {m[8]}, {m[12]},"
|
||||||
|
yield f"{m[1]}, {m[5]}, {m[9]}, {m[13]},"
|
||||||
|
yield f"{m[2]}, {m[6]}, {m[10]}, {m[14]},"
|
||||||
|
yield f"{m[3]}, {m[7]}, {m[11]}, {m[15]},"
|
||||||
|
yield "},"
|
||||||
|
|
||||||
|
def generate_mesh(obj):
|
||||||
|
name = get_obj_name(obj)
|
||||||
|
yield f".n_vertices = {obj.nVertices},"
|
||||||
|
yield f".vertices = {name}_vertices,"
|
||||||
|
yield f".n_faces = {obj.nFaces},"
|
||||||
|
yield f".faces = {name}_faces,"
|
||||||
|
|
||||||
|
def generate_mesh_material_list(obj):
|
||||||
|
name = get_obj_name(obj)
|
||||||
|
yield f".n_materials = {obj.nMaterials},"
|
||||||
|
yield f".n_face_indices = {obj.nFaceIndices},"
|
||||||
|
yield f".face_indices = {name}_face_indices,"
|
||||||
|
|
||||||
|
def generate_mesh_normals(obj):
|
||||||
|
name = get_obj_name(obj)
|
||||||
|
yield f".n_normals = {obj.nNormals},"
|
||||||
|
yield f".normals = {name}_normals,"
|
||||||
|
yield f".n_face_normals = {obj.nFaceNormals},"
|
||||||
|
|
||||||
|
def generate_mesh_texture_coords(obj):
|
||||||
|
yield f".n_texture_coords = {obj.nTextureCoords},"
|
||||||
|
yield f".texture_coords = {{"
|
||||||
|
for tc in obj.textureCoords:
|
||||||
|
coordinates = f"{tc.u}, {tc.v}"
|
||||||
|
yield f"{{{coordinates}}},"
|
||||||
|
yield "},"
|
||||||
|
|
||||||
|
def generate_animation_key(obj):
|
||||||
|
yield f".key_type = {obj.keyType},"
|
||||||
|
yield f".n_keys = {obj.nKeys},"
|
||||||
|
yield ".keys = {"
|
||||||
|
yield "// not implemented"
|
||||||
|
yield "},"
|
||||||
|
|
||||||
|
def generate_animation_options(obj):
|
||||||
|
yield f".open_closed = {obj.openClosed},"
|
||||||
|
yield f".position_quality = {obj.positionQuality},"
|
||||||
|
|
||||||
|
def generate_animation(obj):
|
||||||
|
return
|
||||||
|
yield
|
||||||
|
|
||||||
|
def generate_animation_set(obj):
|
||||||
|
return
|
||||||
|
yield
|
||||||
|
|
||||||
|
def generate_definition(obj):
|
||||||
|
yield f"{type_declaration(obj)} = {{"
|
||||||
|
|
||||||
|
if obj_type(obj) in tagged:
|
||||||
|
yield f".tag = tag::{type_map[obj_type(obj)]},"
|
||||||
|
|
||||||
|
if obj_type(obj) is templates.Header:
|
||||||
|
yield from generate_header(obj_value(obj))
|
||||||
|
elif obj_type(obj) is templates.Material:
|
||||||
|
yield from generate_material(obj_value(obj))
|
||||||
|
elif obj_type(obj) is templates.TextureFilename:
|
||||||
|
yield from generate_texture_filename(obj_value(obj))
|
||||||
|
elif obj_type(obj) is templates.Frame:
|
||||||
|
yield from generate_frame(obj_value(obj))
|
||||||
|
elif obj_type(obj) is templates.FrameTransformMatrix:
|
||||||
|
yield from generate_frame_transform_matrix(obj_value(obj))
|
||||||
|
elif obj_type(obj) is templates.Mesh:
|
||||||
|
yield from generate_mesh(obj_value(obj))
|
||||||
|
elif obj_type(obj) is templates.MeshMaterialList:
|
||||||
|
yield from generate_mesh_material_list(obj_value(obj))
|
||||||
|
elif obj_type(obj) is templates.MeshNormals:
|
||||||
|
yield from generate_mesh_normals(obj_value(obj))
|
||||||
|
elif obj_type(obj) is templates.MeshTextureCoords:
|
||||||
|
yield from generate_mesh_texture_coords(obj_value(obj))
|
||||||
|
elif obj_type(obj) is templates.AnimationKey:
|
||||||
|
yield from generate_animation_key(obj_value(obj))
|
||||||
|
elif obj_type(obj) is templates.AnimationOptions:
|
||||||
|
yield from generate_animation_options(obj_value(obj))
|
||||||
|
elif obj_type(obj) is templates.Animation:
|
||||||
|
yield from generate_animation(obj_value(obj))
|
||||||
|
elif obj_type(obj) is templates.AnimationSet:
|
||||||
|
yield from generate_animation_set(obj_value(obj))
|
||||||
|
elif obj_type(obj) is templates.Reference:
|
||||||
|
# do nothing
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
assert False, (obj_type(obj), obj)
|
||||||
|
|
||||||
|
if visitors[obj_type(obj)] is visit_objects:
|
||||||
|
yield ""
|
||||||
|
yield ".objects = {"
|
||||||
|
for o in obj_value(obj).objects:
|
||||||
|
if obj_type(o) == templates.Reference:
|
||||||
|
reference_name = obj_value(o).name
|
||||||
|
o = obj_map[reference_name]
|
||||||
|
yield f"reinterpret_cast<const data_object *>(&{get_obj_name(o)}),"
|
||||||
|
yield "}"
|
||||||
|
|
||||||
|
yield "};"
|
||||||
|
|
||||||
def visit_all(func, objects):
|
def visit_all(func, objects):
|
||||||
for obj in objects:
|
for obj in objects:
|
||||||
@ -165,6 +322,5 @@ objects = list(parse_all(TokenReader(buf)))
|
|||||||
_ = list(visit_all(add_name_map, objects))
|
_ = list(visit_all(add_name_map, objects))
|
||||||
|
|
||||||
render, out = generate.renderer()
|
render, out = generate.renderer()
|
||||||
for i in gen(objects):
|
render(gen(objects))
|
||||||
print("line", i)
|
|
||||||
print(out.getvalue())
|
print(out.getvalue())
|
||||||
|
@ -7,15 +7,16 @@ def should_autonewline(line):
|
|||||||
and (len(line.split()) < 2 or line.split()[1] != '=') # hacky; meh
|
and (len(line.split()) < 2 or line.split()[1] != '=') # hacky; meh
|
||||||
)
|
)
|
||||||
|
|
||||||
def _render(out, lines):
|
def _render(out, lines, level=0):
|
||||||
indent = " "
|
indent = " "
|
||||||
level = 0
|
|
||||||
for l in lines:
|
for l in lines:
|
||||||
if l and (l[0] == "}" or l[0] == ")"):
|
if l and (l[0] == "}" or l[0] == ")"):
|
||||||
level -= 2
|
level -= 2
|
||||||
assert level >= 0, out.getvalue()
|
assert level >= 0, out.getvalue()
|
||||||
|
|
||||||
if len(l) == 0:
|
if type(l) is tuple:
|
||||||
|
line_fifo.append(l)
|
||||||
|
elif len(l) == 0:
|
||||||
out.write("\n")
|
out.write("\n")
|
||||||
else:
|
else:
|
||||||
out.write(indent * level + l + "\n")
|
out.write(indent * level + l + "\n")
|
||||||
|
28
x/x.hpp
28
x/x.hpp
@ -1,7 +1,7 @@
|
|||||||
/* primitives */
|
/* primitives */
|
||||||
struct mesh_face {
|
struct mesh_face {
|
||||||
int nfacevertexindices;
|
//int n_face_vertex_indices;
|
||||||
int facevertexindices[];
|
int face_vertex_indices[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct float_keys {
|
struct float_keys {
|
||||||
@ -42,11 +42,11 @@ struct header {
|
|||||||
|
|
||||||
struct material {
|
struct material {
|
||||||
enum tag tag;
|
enum tag tag;
|
||||||
vec4 facecolor;
|
vec4 face_color;
|
||||||
float power;
|
float power;
|
||||||
vec3 specularcolor;
|
vec3 specular_color;
|
||||||
vec3 emissivecolor;
|
vec3 emissive_color;
|
||||||
struct data_object * objects[];
|
const data_object * objects[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct texture_filename {
|
struct texture_filename {
|
||||||
@ -56,21 +56,21 @@ struct texture_filename {
|
|||||||
|
|
||||||
struct frame {
|
struct frame {
|
||||||
enum tag tag;
|
enum tag tag;
|
||||||
struct data_object * objects[];
|
const data_object * objects[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct frame_transform_matrix {
|
struct frame_transform_matrix {
|
||||||
enum tag tag;
|
enum tag tag;
|
||||||
mat4x4 framematrix;
|
mat4x4 frame_matrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mesh {
|
struct mesh {
|
||||||
enum tag tag;
|
enum tag tag;
|
||||||
int nvertices;
|
int n_vertices;
|
||||||
vec3 * vertices;
|
vec3 * vertices;
|
||||||
int nfaces;
|
int n_faces;
|
||||||
struct mesh_face * faces;
|
struct mesh_face * faces;
|
||||||
struct data_object * objects[];
|
const data_object * objects[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mesh_material_list {
|
struct mesh_material_list {
|
||||||
@ -78,7 +78,7 @@ struct mesh_material_list {
|
|||||||
int n_materials;
|
int n_materials;
|
||||||
int n_face_indices;
|
int n_face_indices;
|
||||||
int * face_indices;
|
int * face_indices;
|
||||||
struct data_object * objects[];
|
const data_object * objects[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mesh_normals {
|
struct mesh_normals {
|
||||||
@ -110,12 +110,12 @@ struct animation_options {
|
|||||||
|
|
||||||
struct animation {
|
struct animation {
|
||||||
enum tag tag;
|
enum tag tag;
|
||||||
struct data_object * objects[];
|
const data_object * objects[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct animation_set {
|
struct animation_set {
|
||||||
enum tag tag;
|
enum tag tag;
|
||||||
struct data_object * objects[];
|
const data_object * objects[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct data_object {
|
struct data_object {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user