switch to raycast & bvh
[carveJwlIkooP6JGAAIwe30JlM.git] / blender_export.py
1 import bpy, math
2 from ctypes import *
3
4 class model(Structure):
5 _pack_ = 1
6 _fields_ = [("identifier",c_uint32),
7 ("vertex_count",c_uint32),
8 ("indice_count",c_uint32),
9 ("layer_count",c_uint32)]
10
11 class sdf_primative(Structure):
12 _pack_ = 1
13 _fields_ = [("origin",c_float*4),
14 ("info",c_float*4)]
15
16 class submodel(Structure):
17 _pack_ = 1
18 _fields_ = [("indice_start",c_uint32),
19 ("indice_count",c_uint32),
20 ("vertex_start",c_uint32),
21 ("vertex_count",c_uint32),
22 ("bbx",(c_float*3)*2),
23 ("pivot",c_float*3),
24 ("sdf",sdf_primative),
25 ("sdf_type",c_int32),
26 ("name",c_char*32)]
27
28 class model_vert(Structure):
29 _pack_ = 1
30 _fields_ = [("co",c_float*3),
31 ("norm",c_float*3),
32 ("colour",c_float*4),
33 ("uv",c_float*2)]
34
35 def fixed_string(dest,string):
36 return
37 for i in range(len(string)):
38 dest[i] = string[i]
39
40 def write_model(name):
41 fp = open(F"/home/harry/Documents/carve/models/{name}.mdl", "wb")
42 collection = bpy.data.collections[name]
43
44 header = model()
45 header.identifier = 0xABCD0000
46 header.vertex_count = 0
47 header.indice_count = 0
48 header.layer_count = 0
49
50 layers = []
51 vertex_buffer = []
52 indice_buffer = []
53
54 for obj in collection.objects:
55 if obj.type == 'MESH':
56 dgraph = bpy.context.evaluated_depsgraph_get()
57 data = obj.evaluated_get(dgraph).data
58 data.calc_loop_triangles()
59 data.calc_normals_split()
60
61 sm = submodel()
62 sm.indice_start = header.indice_count
63 sm.vertex_start = header.vertex_count
64 sm.vertex_count = len(data.vertices)
65 sm.indice_count = len(data.loop_triangles)*3
66 sm.sdf_type = 0
67 sm.pivot[0] = obj.matrix_world.translation[0]
68 sm.pivot[1] = obj.matrix_world.translation[2]
69 sm.pivot[2] = -obj.matrix_world.translation[1]
70
71 for i in range(3):
72 sm.bbx[0][i] = 999999
73 sm.bbx[1][i] = -999999
74
75 if F"{obj.name}.sdf_cone" in bpy.data.objects:
76 cone = bpy.data.objects[F"{obj.name}.sdf_cone"]
77 sm.sdf.origin[0] = cone.location[0]
78 sm.sdf.origin[1] = cone.location[2] + cone.scale[1]*2.0
79 sm.sdf.origin[2] = -cone.location[1]
80 sm.sdf.origin[3] = 0.0
81
82 lo = cone.scale[0]
83 la = cone.scale[1]*2.0
84 lh = math.sqrt(lo*lo+la*la)
85
86 sm.sdf.info[0] = lo
87 sm.sdf.info[1] = la
88 sm.sdf.info[2] = lo/lh
89 sm.sdf.info[3] = la/lh
90
91 sm.sdf_type = 1
92
93 sm.name = obj.name.encode('utf-8')
94
95 for vert in data.vertices:
96 v = model_vert()
97 v.co[0] = vert.co[0]
98 v.co[1] = vert.co[2]
99 v.co[2] = -vert.co[1]
100 v.colour[0] = 1.0
101 v.colour[1] = 1.0
102 v.colour[2] = 1.0
103 v.colour[3] = 1.0
104 vertex_buffer += [v]
105
106 for i in range(3):
107 sm.bbx[0][i] = min( sm.bbx[0][i], v.co[i] )
108 sm.bbx[1][i] = max( sm.bbx[1][i], v.co[i] )
109
110 for l in data.loops:
111 pvert = vertex_buffer[l.vertex_index + sm.vertex_start]
112 norm = l.normal
113 pvert.norm[0] = norm[0]
114 pvert.norm[1] = norm[2]
115 pvert.norm[2] = -norm[1]
116
117 #if data.vertex_colors:
118 # colour = data.vertex_colors.active.data[ l.index ].color
119 # pvert.colour[0] = colour[0]
120
121 if data.uv_layers:
122 uv = data.uv_layers.active.data[ l.index ].uv
123 pvert.uv[0] = uv[0]
124 pvert.uv[1] = uv[1]
125
126 for tri in data.loop_triangles:
127 indice_buffer += [c_uint32(tri.vertices[_]) for _ in range(3)]
128
129 layers += [sm]
130 header.layer_count += 1
131 header.vertex_count += sm.vertex_count
132 header.indice_count += sm.indice_count
133
134 fp.write( bytearray( header ) )
135 for l in layers:
136 fp.write( bytearray(l) )
137 for v in vertex_buffer:
138 fp.write( bytearray(v) )
139 for i in indice_buffer:
140 fp.write( bytearray(i) )
141
142 fp.close()
143
144 for col in bpy.data.collections["export"].children:
145 write_model( col.name )