blender.py: add support for textures
This commit is contained in:
parent
3bd28fd814
commit
34eeda47be
81
blender.py
81
blender.py
@ -1,4 +1,5 @@
|
|||||||
import bpy
|
import bpy
|
||||||
|
from os import path
|
||||||
|
|
||||||
def render_vec3(v):
|
def render_vec3(v):
|
||||||
return f"{{{v.x:.6f}, {v.y:.6f}, {v.z:.6f}}}"
|
return f"{{{v.x:.6f}, {v.y:.6f}, {v.z:.6f}}}"
|
||||||
@ -24,18 +25,25 @@ def render_polygon_normals(f, name, polygon_normals):
|
|||||||
f.write(f" {render_vec3(normal.vector)},\n")
|
f.write(f" {render_vec3(normal.vector)},\n")
|
||||||
f.write("};\n\n")
|
f.write("};\n\n")
|
||||||
|
|
||||||
|
def sort_by_material(polygons):
|
||||||
|
return sorted(polygons, key=lambda p: p.material_index)
|
||||||
|
|
||||||
def render_polygons(f, name, polygons):
|
def render_polygons(f, name, polygons):
|
||||||
f.write(f"const polygon {name}_polygons[] = {{\n")
|
f.write(f"const polygon {name}_polygons[] = {{\n")
|
||||||
for i, polygon in enumerate(polygons):
|
|
||||||
s = ", ".join(map(str, polygon.vertices))
|
|
||||||
c = "// " if len(polygon.vertices) != 4 else ""
|
|
||||||
|
|
||||||
f.write(f" {c}{{{s}}},\n")
|
uv_ix = 0
|
||||||
|
for i, polygon in enumerate(polygons):
|
||||||
|
indices = [*polygon.vertices, polygon.material_index, uv_ix]
|
||||||
|
uv_ix += len(polygon.vertices)
|
||||||
|
s = ", ".join(map(str, indices))
|
||||||
|
if len(polygon.vertices) == 4:
|
||||||
|
f.write(f" {{{s}}},\n")
|
||||||
|
else:
|
||||||
|
f.write(f" {{0, 0, 0, 0, -1}}, // {{{s}}}\n")
|
||||||
f.write("};\n\n")
|
f.write("};\n\n")
|
||||||
|
|
||||||
def render_uv_map(f, name, name2, uvm):
|
def render_uv_map(f, name, name2, uvm):
|
||||||
f.write(f"const vec2 {name}_{name2}_uvmap[] = {{\n")
|
f.write(f"const vec2 {name}_{name2}_uvmap[] = {{\n")
|
||||||
print(uvm)
|
|
||||||
for uv in uvm:
|
for uv in uvm:
|
||||||
s = render_vec2(uv.vector)
|
s = render_vec2(uv.vector)
|
||||||
f.write(f" {s},\n")
|
f.write(f" {s},\n")
|
||||||
@ -74,6 +82,8 @@ def render_mesh(f, name, mesh):
|
|||||||
f.write(f" .polygons_length = (sizeof ({name}_polygons)) / (sizeof ({name}_polygons[0])),\n")
|
f.write(f" .polygons_length = (sizeof ({name}_polygons)) / (sizeof ({name}_polygons[0])),\n")
|
||||||
f.write(f" .uv_layers = {name}_uv_layers,\n")
|
f.write(f" .uv_layers = {name}_uv_layers,\n")
|
||||||
f.write(f" .uv_layers_length = (sizeof ({name}_uv_layers)) / (sizeof ({name}_uv_layers[0])),\n")
|
f.write(f" .uv_layers_length = (sizeof ({name}_uv_layers)) / (sizeof ({name}_uv_layers[0])),\n")
|
||||||
|
f.write(f" .materials = {name}_materials,\n")
|
||||||
|
f.write(f" .materials_length = (sizeof ({name}_materials)) / (sizeof ({name}_materials[0])),\n")
|
||||||
f.write( "};\n\n")
|
f.write( "};\n\n")
|
||||||
|
|
||||||
def translate_name(name):
|
def translate_name(name):
|
||||||
@ -81,6 +91,8 @@ def translate_name(name):
|
|||||||
|
|
||||||
def mesh_objects(objects):
|
def mesh_objects(objects):
|
||||||
for object in objects:
|
for object in objects:
|
||||||
|
if object.hide_get():
|
||||||
|
continue
|
||||||
if object.type == "MESH":
|
if object.type == "MESH":
|
||||||
yield object
|
yield object
|
||||||
|
|
||||||
@ -93,6 +105,58 @@ def mesh_meshes(objects):
|
|||||||
mesh_names.add(mesh.name)
|
mesh_names.add(mesh.name)
|
||||||
yield mesh
|
yield mesh
|
||||||
|
|
||||||
|
def get_texture(material):
|
||||||
|
assert material.use_nodes, material.name
|
||||||
|
for node in material.node_tree.nodes:
|
||||||
|
if node.type == "TEX_IMAGE":
|
||||||
|
return node.image
|
||||||
|
|
||||||
|
_offset = 0
|
||||||
|
texture_offsets = {}
|
||||||
|
prefix = "textures_"
|
||||||
|
|
||||||
|
def get_texture_offset(image):
|
||||||
|
global _offset
|
||||||
|
if image.name in texture_offsets:
|
||||||
|
value = texture_offsets[image.name]
|
||||||
|
return value
|
||||||
|
value = _offset
|
||||||
|
texture_offsets[image.name] = value
|
||||||
|
width, height = image.size
|
||||||
|
_offset += width * height // 4 + 256 * 4 * 2
|
||||||
|
return value
|
||||||
|
|
||||||
|
def texture_data_name(name):
|
||||||
|
name = path.splitext(name)[0]
|
||||||
|
name = translate_name(name)
|
||||||
|
return f"{prefix}{name}_vq"
|
||||||
|
|
||||||
|
def render_mesh_materials(f, name, materials):
|
||||||
|
f.write(f"const mesh_material {name}_materials[] = {{\n")
|
||||||
|
for material in materials:
|
||||||
|
image = get_texture(material)
|
||||||
|
assert image is not None, material.name
|
||||||
|
f.write(f" {{ // {material.name} {image.name}\n")
|
||||||
|
width, height = image.size
|
||||||
|
offset = get_texture_offset(image)
|
||||||
|
f.write(f" .width = {width},\n")
|
||||||
|
f.write(f" .height = {height},\n")
|
||||||
|
f.write(f" .offset = {offset},\n")
|
||||||
|
f.write(" },\n")
|
||||||
|
f.write("};\n")
|
||||||
|
|
||||||
|
def render_materials(f):
|
||||||
|
f.write("const material materials[] = {\n")
|
||||||
|
for image_name, offset in texture_offsets.items():
|
||||||
|
name = texture_data_name(image_name)
|
||||||
|
print(image_name)
|
||||||
|
f.write(" {\n")
|
||||||
|
f.write(f" .start = (void *)&_binary_{name}_start,\n")
|
||||||
|
f.write(f" .size = (int)&_binary_{name}_size,\n")
|
||||||
|
f.write(f" .offset = {offset},\n")
|
||||||
|
f.write(" },\n")
|
||||||
|
f.write("};\n");
|
||||||
|
|
||||||
def export_meshes(f):
|
def export_meshes(f):
|
||||||
for mesh in mesh_meshes(bpy.context.scene.objects):
|
for mesh in mesh_meshes(bpy.context.scene.objects):
|
||||||
#mesh.vertex_normals
|
#mesh.vertex_normals
|
||||||
@ -111,7 +175,7 @@ def export_meshes(f):
|
|||||||
render_vertex_normals(f, mesh_name, mesh.vertices)
|
render_vertex_normals(f, mesh_name, mesh.vertices)
|
||||||
render_polygon_normals(f, mesh_name, mesh.polygon_normals)
|
render_polygon_normals(f, mesh_name, mesh.polygon_normals)
|
||||||
render_polygons(f, mesh_name, mesh.polygons)
|
render_polygons(f, mesh_name, mesh.polygons)
|
||||||
|
render_mesh_materials(f, mesh_name, mesh.materials)
|
||||||
|
|
||||||
render_mesh(f, mesh_name, mesh);
|
render_mesh(f, mesh_name, mesh);
|
||||||
|
|
||||||
@ -128,8 +192,9 @@ def mesh_objects_sorted(objects):
|
|||||||
return sorted(mesh_objects(objects), key=key)
|
return sorted(mesh_objects(objects), key=key)
|
||||||
|
|
||||||
def export_objects(f):
|
def export_objects(f):
|
||||||
f.write("const struct object objects[] = {\n")
|
f.write("const object objects[] = {\n")
|
||||||
for object in mesh_objects_sorted(bpy.context.scene.objects):
|
for object in mesh_objects_sorted(bpy.context.scene.objects):
|
||||||
|
|
||||||
#object.rotation_mode = 'AXIS_ANGLE'
|
#object.rotation_mode = 'AXIS_ANGLE'
|
||||||
#object.name
|
#object.name
|
||||||
#object.rotation_axis_angle
|
#object.rotation_axis_angle
|
||||||
@ -159,6 +224,8 @@ def export_objects(f):
|
|||||||
def export_scene(f):
|
def export_scene(f):
|
||||||
export_meshes(f)
|
export_meshes(f)
|
||||||
export_objects(f)
|
export_objects(f)
|
||||||
|
render_materials(f)
|
||||||
|
|
||||||
with open("/home/bilbo/output.h", "w") as f:
|
with open("/home/bilbo/output.h", "w") as f:
|
||||||
|
offset = 0
|
||||||
export_scene(f)
|
export_scene(f)
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
struct polygon {
|
struct polygon {
|
||||||
int a, b, c, d;
|
int a, b, c, d;
|
||||||
|
int material_index;
|
||||||
|
int uv_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mesh_material {
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mesh {
|
struct mesh {
|
||||||
@ -13,6 +21,8 @@ struct mesh {
|
|||||||
const int polygons_length;
|
const int polygons_length;
|
||||||
const vec2 ** uv_layers;
|
const vec2 ** uv_layers;
|
||||||
const int uv_layers_length;
|
const int uv_layers_length;
|
||||||
|
const mesh_material * materials;
|
||||||
|
const int materials_length;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct object {
|
struct object {
|
||||||
@ -21,3 +31,9 @@ struct object {
|
|||||||
const vec4 rotation;
|
const vec4 rotation;
|
||||||
const vec3 location;
|
const vec3 location;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct material {
|
||||||
|
void * start;
|
||||||
|
int size;
|
||||||
|
int offset;
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user