e52757b16d6edbbb1b12e3ca3456376c59ae3463
4 from mathutils
import *
5 from gpu_extras
.batch
import batch_for_shader
8 "name":"Carve exporter",
9 "author": "Harry Godden (hgn)",
16 "category":"Import/Export",
19 class mdl_vert(Structure
):
21 _fields_
= [("co",c_float
*3),
26 class mdl_submesh(Structure
):
28 _fields_
= [("indice_start",c_uint32
),
29 ("indice_count",c_uint32
),
30 ("vertex_start",c_uint32
),
31 ("vertex_count",c_uint32
),
32 ("bbx",(c_float
*3)*2),
33 ("material_id",c_uint32
)] # index into the material array
35 class mdl_material(Structure
):
37 _fields_
= [("pstr_name",c_uint32
)]
39 class mdl_node(Structure
):
41 _fields_
= [("co",c_float
*3),
44 ("submesh_start",c_uint32
),
45 ("submesh_count",c_uint32
),
46 ("classtype",c_uint32
),
48 ("pstr_name",c_uint32
)]
50 class mdl_header(Structure
):
52 _fields_
= [("identifier",c_uint32
),
54 ("file_length",c_uint32
),
55 ("vertex_count",c_uint32
),
56 ("vertex_offset",c_uint32
),
58 ("indice_count",c_uint32
),
59 ("indice_offset",c_uint32
),
61 ("submesh_count",c_uint32
),
62 ("submesh_offset",c_uint32
),
64 ("material_count",c_uint32
),
65 ("material_offset",c_uint32
),
67 ("node_count",c_uint32
),
68 ("node_offset",c_uint32
),
70 ("strings_offset",c_uint32
),
71 ("entdata_offset",c_uint32
)
75 # ==========================================
77 class classtype_gate(Structure
):
79 _fields_
= [("target",c_uint32
),
82 class classtype_block(Structure
):
84 _fields_
= [("bbx",(c_float
*3)*2)]
86 class classtype_spawn(Structure
):
88 _fields_
= [("temp",c_uint32
)]
90 class classtype_water(Structure
):
92 _fields_
= [("temp",c_uint32
)]
94 class classtype_car_path(Structure
):
96 _fields_
= [("target",c_uint32
),
99 class classtype_instance(Structure
):
101 _fields_
= [("pstr_file",c_uint32
)]
103 class classtype_capsule(Structure
):
105 _fields_
= [("height",c_float
),
108 class classtype_route_node(Structure
):
110 _fields_
= [("target",c_uint32
),
111 ("target1",c_uint32
)]
113 class classtype_route(Structure
):
115 _fields_
= [("pstr_name",c_uint32
),
116 ("id_start",c_uint32
)]
119 # ==============================================================================
121 def write_model(name
):
122 print( F
"Create mode {name}" )
124 header
= mdl_header()
125 header
.identifier
= 0xABCD0000
127 header
.vertex_count
= 0
128 header
.indice_count
= 0
129 header
.submesh_count
= 0
130 header
.node_count
= 0
131 header
.material_count
= 0
132 header
.file_length
= 0
148 def emplace_string( s
):
149 nonlocal string_cache
, strings_buffer
151 if s
in string_cache
:
152 return string_cache
[s
]
154 string_cache
[s
] = len( strings_buffer
)
155 strings_buffer
+= (s
+'\0').encode('utf-8')
156 return string_cache
[s
]
158 def emplace_material( mat
):
159 nonlocal material_cache
, material_buffer
161 if mat
.name
in material_cache
:
162 return material_cache
[mat
.name
]
164 material_cache
[mat
.name
] = header
.material_count
165 dest
= mdl_material()
166 dest
.pstr_name
= emplace_string( mat
.name
)
167 material_buffer
+= [dest
]
169 header
.material_count
+= 1
170 return material_cache
[mat
.name
]
172 # Create root or empty node and materials
174 none_material
= c_uint32(69)
175 none_material
.name
= ""
176 emplace_material( none_material
)
189 root
.pstr_name
= emplace_string('')
190 root
.submesh_start
= 0
191 root
.submesh_count
= 0
194 node_buffer
+= [root
]
198 print( " assigning ids" )
199 collection
= bpy
.data
.collections
[name
]
201 header
.node_count
= 1
202 for obj
in collection
.all_objects
:
203 obj
.cv_data
.uid
= header
.node_count
204 header
.node_count
+= 1
206 print( " compiling data" )
207 for obj
in collection
.all_objects
:
208 print( F
" [{obj.cv_data.uid}/{header.node_count-1}] {obj.name}" )
211 node
.co
[0] = obj
.location
[0]
212 node
.co
[1] = obj
.location
[2]
213 node
.co
[2] = -obj
.location
[1]
215 # Convert rotation quat to our space type
216 quat
= obj
.matrix_world
.to_quaternion()
222 node
.s
[0] = obj
.scale
[0]
223 node
.s
[1] = obj
.scale
[2]
224 node
.s
[2] = obj
.scale
[1]
225 node
.pstr_name
= emplace_string( obj
.name
)
227 # Process entity data
229 node
.offset
= entdata_length
230 classtype
= obj
.cv_data
.classtype
232 if classtype
== 'k_classtype_gate':
234 entdata_length
+= sizeof( classtype_gate
)
236 gate
= classtype_gate()
238 if obj
.cv_data
.target
!= None:
239 gate
.target
= obj
.cv_data
.target
.cv_data
.uid
241 if obj
.type == 'MESH':
242 gate
.dims
[0] = obj
.data
.cv_data
.v0
[0]
243 gate
.dims
[1] = obj
.data
.cv_data
.v0
[1]
244 gate
.dims
[2] = obj
.data
.cv_data
.v0
[2]
246 gate
.dims
[0] = obj
.cv_data
.v0
[0]
247 gate
.dims
[1] = obj
.cv_data
.v0
[1]
248 gate
.dims
[2] = obj
.cv_data
.v0
[2]
250 entdata_buffer
+= [gate
]
252 elif classtype
== 'k_classtype_block':
254 entdata_length
+= sizeof( classtype_block
)
256 source
= obj
.data
.cv_data
258 block
= classtype_block()
259 block
.bbx
[0][0] = source
.v0
[0]
260 block
.bbx
[0][1] = source
.v0
[2]
261 block
.bbx
[0][2] = -source
.v1
[1]
263 block
.bbx
[1][0] = source
.v1
[0]
264 block
.bbx
[1][1] = source
.v1
[2]
265 block
.bbx
[1][2] = -source
.v0
[1]
266 entdata_buffer
+= [block
]
268 elif classtype
== 'k_classtype_spawn':
271 elif classtype
== 'k_classtype_water':
273 elif classtype
== 'k_classtype_car_path':
275 entdata_length
+= sizeof( classtype_car_path
)
277 pn
= classtype_car_path()
281 if obj
.cv_data
.target
!= None:
282 pn
.target
= obj
.cv_data
.target
.cv_data
.uid
283 if obj
.cv_data
.target1
!= None:
284 pn
.target1
= obj
.cv_data
.target1
.cv_data
.uid
286 entdata_buffer
+= [pn
]
287 elif obj
.is_instancer
:
288 target
= obj
.instance_collection
291 entdata_length
+= sizeof( classtype_instance
)
293 inst
= classtype_instance()
294 inst
.pstr_file
= emplace_string( F
"models/{target.name}.mdl" )
295 entdata_buffer
+= [inst
]
296 elif classtype
== 'k_classtype_capsule':
298 elif classtype
== 'k_classtype_route_node':
300 entdata_length
+= sizeof( classtype_route_node
)
302 rn
= classtype_route_node()
303 if obj
.cv_data
.target
!= None:
304 rn
.target
= obj
.cv_data
.target
.cv_data
.uid
305 if obj
.cv_data
.target1
!= None:
306 rn
.target1
= obj
.cv_data
.target1
.cv_data
.uid
308 entdata_buffer
+= [rn
]
309 elif classtype
== 'k_classtype_route':
311 entdata_length
+= sizeof( classtype_route
)
312 r
= classtype_route()
313 r
.pstr_name
= emplace_string("not-implemented")
314 if obj
.cv_data
.target
!= None:
315 r
.target
= obj
.cv_data
.target
.cv_data
.uid
317 entdata_buffer
+= [r
]
319 # classtype == 'k_classtype_none':
326 node
.submesh_start
= header
.submesh_count
327 node
.submesh_count
= 0
329 if obj
.type == 'MESH':
330 default_mat
= c_uint32(69)
331 default_mat
.name
= ""
333 # Dont use the cache if we have modifiers that affect the normals
336 for mod
in obj
.modifiers
:
337 if mod
.type == 'DATA_TRANSFER':
340 if use_cache
and obj
.data
.name
in mesh_cache
:
341 ref
= mesh_cache
[obj
.data
.name
]
342 node
.submesh_start
= ref
.submesh_start
343 node
.submesh_count
= ref
.submesh_count
344 node_buffer
+= [node
]
347 dgraph
= bpy
.context
.evaluated_depsgraph_get()
348 data
= obj
.evaluated_get(dgraph
).data
349 data
.calc_loop_triangles()
350 data
.calc_normals_split()
352 mat_list
= data
.materials
if len(data
.materials
) > 0 else [default_mat
]
353 for material_id
, mat
in enumerate(mat_list
):
357 sm
.indice_start
= header
.indice_count
358 sm
.vertex_start
= header
.vertex_count
361 sm
.material_id
= emplace_material( mat
)
364 sm
.bbx
[0][i
] = 999999
365 sm
.bbx
[1][i
] = -999999
369 # Write the vertex / indice data
371 for tri_index
, tri
in enumerate(data
.loop_triangles
):
372 if tri
.material_index
!= material_id
:
376 vert
= data
.vertices
[tri
.vertices
[j
]]
380 norm
= data
.loops
[li
].normal
384 uv
= data
.uv_layers
.active
.data
[li
].uv
385 if data
.vertex_colors
:
386 colour
= data
.vertex_colors
.active
.data
[li
].color
389 m
= float(10**TOLERENCE
)
391 key
= (int(co
[0]*m
+0.5),\
399 int(colour
[0]*m
+0.5),\
400 int(colour
[1]*m
+0.5),\
401 int(colour
[2]*m
+0.5),\
402 int(colour
[3]*m
+0.5))
405 indice_buffer
+= [boffa
[key
]]
407 index
= c_uint32(sm
.vertex_count
)
411 indice_buffer
+= [index
]
422 v
.colour
[0] = colour
[0]
423 v
.colour
[1] = colour
[1]
424 v
.colour
[2] = colour
[2]
425 v
.colour
[3] = colour
[3]
429 sm
.bbx
[0][i
] = min( sm
.bbx
[0][i
], v
.co
[i
] )
430 sm
.bbx
[1][i
] = max( sm
.bbx
[1][i
], v
.co
[i
] )
434 if sm
.vertex_count
== 0:
439 submesh_buffer
+= [sm
]
440 node
.submesh_count
+= 1
441 header
.submesh_count
+= 1
442 header
.vertex_count
+= sm
.vertex_count
443 header
.indice_count
+= sm
.indice_count
445 mesh_cache
[obj
.data
.name
] = node
446 node_buffer
+= [node
]
450 print( "Writing data" )
451 fpos
= sizeof(header
)
453 header
.node_offset
= fpos
454 fpos
+= sizeof(mdl_node
)*header
.node_count
456 header
.submesh_offset
= fpos
457 fpos
+= sizeof(mdl_submesh
)*header
.submesh_count
459 header
.material_offset
= fpos
460 fpos
+= sizeof(mdl_material
)*header
.material_count
462 header
.entdata_offset
= fpos
463 fpos
+= entdata_length
465 header
.vertex_offset
= fpos
466 fpos
+= sizeof(mdl_vert
)*header
.vertex_count
468 header
.indice_offset
= fpos
469 fpos
+= sizeof(c_uint32
)*header
.indice_count
471 header
.strings_offset
= fpos
472 fpos
+= len(strings_buffer
)
474 header
.file_length
= fpos
476 fp
= open(F
"/home/harry/Documents/carve/models/{name}.mdl", "wb")
477 fp
.write( bytearray( header
) )
479 for node
in node_buffer
:
480 fp
.write( bytearray(node
) )
481 for sm
in submesh_buffer
:
482 fp
.write( bytearray(sm
) )
483 for mat
in material_buffer
:
484 fp
.write( bytearray(mat
) )
485 for ed
in entdata_buffer
:
486 fp
.write( bytearray(ed
) )
487 for v
in vertex_buffer
:
488 fp
.write( bytearray(v
) )
489 for i
in indice_buffer
:
490 fp
.write( bytearray(i
) )
491 fp
.write( strings_buffer
)
494 print( F
"Completed {name}.mdl" )
497 # ------------------------------------------------------------------------------
499 cv_view_draw_handler
= None
500 cv_view_shader
= gpu
.shader
.from_builtin('3D_SMOOTH_COLOR')
503 global cv_view_shader
504 cv_view_shader
.bind()
505 gpu
.state
.depth_mask_set(False)
506 gpu
.state
.line_width_set(2.0)
507 gpu
.state
.face_culling_set('BACK')
508 gpu
.state
.depth_test_set('LESS')
509 gpu
.state
.blend_set('NONE')
514 #def drawbezier(p0,h0,p1,h1,c0,c1):
515 # nonlocal verts, colours
519 # colours += [(0.5,0.5,0.5,1.0),(0.5,0.5,0.5,1)]
522 # colours += [(1.0,1.0,1,1),(1,1,1,1)]
525 # for i in range(10):
531 # p=ttt*p1+(3*tt-3*ttt)*h1+(3*ttt-6*tt+3*t)*h0+(3*tt-ttt-3*t+1)*p0
532 # verts += [(last[0],last[1],last[2])]
533 # verts += [(p[0],p[1],p[2])]
534 # colours += [c0*a0+c1*(1-a0),c0*a0+c1*(1-a0)]
539 def drawbhandle(obj
, direction
, colour
):
540 nonlocal verts
, colours
542 h0
= obj
.matrix_world
@ Vector((0,direction
,0))
545 colours
+= [colour
,colour
]
547 def drawbezier(p0
,h0
,p1
,h1
,c0
,c1
):
548 nonlocal verts
, colours
557 p
=ttt
*p1
+(3*tt
-3*ttt
)*h1
+(3*ttt
-6*tt
+3*t
)*h0
+(3*tt
-ttt
-3*t
+1)*p0
558 verts
+= [(last
[0],last
[1],last
[2])]
559 verts
+= [(p
[0],p
[1],p
[2])]
560 colours
+= [c0
*a0
+c1
*(1-a0
),c0
*a0
+c1
*(1-a0
)]
563 def drawsbpath(o0
,o1
,c0
,c1
,s0
,s1
):
564 nonlocal course_count
566 offs
= ((course_count
% 2)*2-1) * course_count
* 0.02
568 p0
= o0
.matrix_world
@ Vector((offs
, 0,0))
569 h0
= o0
.matrix_world
@ Vector((offs
, s0
,0))
570 p1
= o1
.matrix_world
@ Vector((offs
, 0,0))
571 h1
= o1
.matrix_world
@ Vector((offs
,-s1
,0))
572 drawbezier(p0
,h0
,p1
,h1
,c0
,c1
)
574 def drawbpath(o0
,o1
,c0
,c1
):
575 drawsbpath(o0
,o1
,c0
,c1
,1.0,1.0)
577 def drawbline(o0
,o1
,c0
,c1
):
578 nonlocal verts
, colours
579 verts
+= [o0
.location
]
580 verts
+= [o1
.location
]
583 for obj
in bpy
.context
.collection
.objects
:
584 if obj
.cv_data
.classtype
== 'k_classtype_gate' and False:
585 if obj
.cv_data
.target
!= None:
587 p1
= obj
.cv_data
.target
.location
594 pb
= p0
*t1
+p1
*(1.0-t1
)
596 verts
+= [(pa
[0],pa
[1],pa
[2])]
597 verts
+= [(pb
[0],pb
[1],pb
[2])]
598 colours
+= [(0,1,0,1.0),(1,0,0,1.0)]
600 if obj
.type == 'MESH':
601 dims
= obj
.data
.cv_data
.v0
603 dims
= obj
.cv_data
.v0
606 c
= Vector((0,0,dims
[2]))
608 vs
[0] = obj
.matrix_world
@ Vector((-dims
[0],0.0,-dims
[1]+dims
[2]))
609 vs
[1] = obj
.matrix_world
@ Vector((-dims
[0],0.0, dims
[1]+dims
[2]))
610 vs
[2] = obj
.matrix_world
@ Vector(( dims
[0],0.0, dims
[1]+dims
[2]))
611 vs
[3] = obj
.matrix_world
@ Vector(( dims
[0],0.0,-dims
[1]+dims
[2]))
612 vs
[4] = obj
.matrix_world
@ (c
+Vector((-1,0,-2)))
613 vs
[5] = obj
.matrix_world
@ (c
+Vector((-1,0, 2)))
614 vs
[6] = obj
.matrix_world
@ (c
+Vector(( 1,0, 2)))
615 vs
[7] = obj
.matrix_world
@ (c
+Vector((-1,0, 0)))
616 vs
[8] = obj
.matrix_world
@ (c
+Vector(( 1,0, 0)))
618 indices
= [(0,1),(1,2),(2,3),(3,0),(4,5),(5,6),(7,8)]
623 verts
+= [(v0
[0],v0
[1],v0
[2])]
624 verts
+= [(v1
[0],v1
[1],v1
[2])]
625 colours
+= [(1,1,0,1),(1,1,0,1)]
627 elif obj
.cv_data
.classtype
== 'k_classtype_block':
628 a
= obj
.data
.cv_data
.v0
629 b
= obj
.data
.cv_data
.v1
632 vs
[0] = obj
.matrix_world
@ Vector((a
[0], a
[1], a
[2]))
633 vs
[1] = obj
.matrix_world
@ Vector((a
[0], b
[1], a
[2]))
634 vs
[2] = obj
.matrix_world
@ Vector((b
[0], b
[1], a
[2]))
635 vs
[3] = obj
.matrix_world
@ Vector((b
[0], a
[1], a
[2]))
636 vs
[4] = obj
.matrix_world
@ Vector((a
[0], a
[1], b
[2]))
637 vs
[5] = obj
.matrix_world
@ Vector((a
[0], b
[1], b
[2]))
638 vs
[6] = obj
.matrix_world
@ Vector((b
[0], b
[1], b
[2]))
639 vs
[7] = obj
.matrix_world
@ Vector((b
[0], a
[1], b
[2]))
641 indices
= [(0,1),(1,2),(2,3),(3,0),(4,5),(5,6),(6,7),(7,4),\
642 (0,4),(1,5),(2,6),(3,7)]
647 verts
+= [(v0
[0],v0
[1],v0
[2])]
648 verts
+= [(v1
[0],v1
[1],v1
[2])]
649 colours
+= [(1,1,0,1),(1,1,0,1)]
651 elif obj
.cv_data
.classtype
== 'k_classtype_capsule':
652 h
= obj
.data
.cv_data
.v0
[0]
653 r
= obj
.data
.cv_data
.v0
[1]
656 vs
[0] = obj
.matrix_world
@ Vector((0.0,0.0, h
*0.5 ))
657 vs
[1] = obj
.matrix_world
@ Vector((0.0,0.0,-h
*0.5 ))
658 vs
[2] = obj
.matrix_world
@ Vector(( r
,0.0, h
*0.5-r
))
659 vs
[3] = obj
.matrix_world
@ Vector(( -r
,0.0, h
*0.5-r
))
660 vs
[4] = obj
.matrix_world
@ Vector(( r
,0.0,-h
*0.5+r
))
661 vs
[5] = obj
.matrix_world
@ Vector(( -r
,0.0,-h
*0.5+r
))
662 vs
[6] = obj
.matrix_world
@ Vector((0.0, r
, h
*0.5-r
))
663 vs
[7] = obj
.matrix_world
@ Vector((0.0,-r
, h
*0.5-r
))
664 vs
[8] = obj
.matrix_world
@ Vector((0.0, r
,-h
*0.5+r
))
665 vs
[9] = obj
.matrix_world
@ Vector((0.0,-r
,-h
*0.5+r
))
667 indices
= [(0,1),(2,3),(4,5),(6,7),(8,9)]
672 verts
+= [(v0
[0],v0
[1],v0
[2])]
673 verts
+= [(v1
[0],v1
[1],v1
[2])]
674 colours
+= [(0.5,1,0,1),(0.5,1,0,1)]
676 elif obj
.cv_data
.classtype
== 'k_classtype_spawn':
678 vs
[0] = obj
.matrix_world
@ Vector((0,0,0))
679 vs
[1] = obj
.matrix_world
@ Vector((0,2,0))
680 vs
[2] = obj
.matrix_world
@ Vector((0.5,1,0))
681 vs
[3] = obj
.matrix_world
@ Vector((-0.5,1,0))
682 indices
= [(0,1),(1,2),(1,3)]
686 verts
+= [(v0
[0],v0
[1],v0
[2])]
687 verts
+= [(v1
[0],v1
[1],v1
[2])]
688 colours
+= [(0,1,1,1),(0,1,1,1)]
690 elif obj
.cv_data
.classtype
== 'k_classtype_route':
693 vs
[1] = obj
.cv_data
.target
.location
698 verts
+= [(v0
[0],v0
[1],v0
[2])]
699 verts
+= [(v1
[0],v1
[1],v1
[2])]
700 colours
+= [(0,1,1,1),(0,1,1,1)]
704 stack
[0] = obj
.cv_data
.target
706 loop_complete
= False
711 targets
= [None,None]
712 targets
[0] = node
.cv_data
.target
714 if node
.cv_data
.classtype
== 'k_classtype_route_node':
715 targets
[1] = node
.cv_data
.target1
717 nextnode
= targets
[stack_i
[si
-1]]
720 if nextnode
!= None: # branch
721 if nextnode
== stack
[0]: # Loop completed
727 if stack
[sj
] == nextnode
: # invalidated path
737 if stack_i
[si
-1] == 2:
740 if si
== 0: # Loop failed to complete
744 course_colours
= [Vector((0,0.8,0.2,1.0)), \
745 Vector((0,0.3,0.9,1.0)), \
746 Vector((0.4,0.0,0.8,1.0)),\
747 Vector((0.5,0.8,0.0,1.0)),\
748 Vector((0.0,0.7,0.6,1.0)),\
749 Vector((0.2,0.9,0.5,1.0)) ]
751 cc
= course_colours
[ course_count
% len(course_colours
) ]
756 if stack
[sj
].cv_data
.classtype
== 'k_classtype_gate' and \
757 stack
[sk
].cv_data
.classtype
== 'k_classtype_gate':
758 dist
= (stack
[sj
].location
-stack
[sk
].location
).magnitude
759 drawsbpath( stack
[sj
], stack
[sk
], cc
*0.4, cc
, dist
, dist
)
762 drawbpath( stack
[sj
], stack
[sk
], cc
, cc
)
766 elif obj
.cv_data
.classtype
== 'k_classtype_car_path':
767 v0
= obj
.matrix_world
.to_quaternion() @ Vector((0,1,0))
768 c0
= Vector((v0
.x
*0.5+0.5, v0
.y
*0.5+0.5, 0.0, 1.0))
769 drawbhandle( obj
, 1.0, (0.9,0.9,0.9,1.0) )
771 if obj
.cv_data
.target
!= None:
772 v1
= obj
.cv_data
.target
.matrix_world
.to_quaternion()@Vector((0,1,0))
773 c1
= Vector((v1
.x
*0.5+0.5, v1
.y
*0.5+0.5, 0.0, 1.0))
775 drawbhandle( obj
.cv_data
.target
, -1.0, (0.5,0.5,0.5,1.0) )
776 drawbpath( obj
, obj
.cv_data
.target
, c0
, c1
)
778 if obj
.cv_data
.target1
!= None:
779 v1
= obj
.cv_data
.target1
.matrix_world
.to_quaternion()@Vector((0,1,0))
780 c1
= Vector((v1
.x
*0.5+0.5, v1
.y
*0.5+0.5, 0.0, 1.0))
782 drawbhandle( obj
.cv_data
.target1
, -1.0, (0.5,0.5,0.5,1.0) )
783 drawbpath( obj
, obj
.cv_data
.target1
, c0
, c1
)
785 lines
= batch_for_shader(\
786 cv_view_shader
, 'LINES', \
787 { "pos":verts
, "color":colours
})
789 lines
.draw( cv_view_shader
)
791 def cv_poll_target(scene
, obj
):
792 if obj
== bpy
.context
.active_object
:
794 if obj
.cv_data
.classtype
== 'k_classtype_none':
798 class CV_MESH_SETTINGS(bpy
.types
.PropertyGroup
):
799 v0
: bpy
.props
.FloatVectorProperty(name
="v0",size
=3)
800 v1
: bpy
.props
.FloatVectorProperty(name
="v1",size
=3)
801 v2
: bpy
.props
.FloatVectorProperty(name
="v2",size
=3)
802 v3
: bpy
.props
.FloatVectorProperty(name
="v3",size
=3)
804 class CV_OBJ_SETTINGS(bpy
.types
.PropertyGroup
):
805 uid
: bpy
.props
.IntProperty( name
="" )
807 target
: bpy
.props
.PointerProperty( type=bpy
.types
.Object
, name
="target", \
808 poll
=cv_poll_target
)
809 target1
: bpy
.props
.PointerProperty( type=bpy
.types
.Object
, name
="target1", \
810 poll
=cv_poll_target
)
812 classtype
: bpy
.props
.EnumProperty(
815 ('k_classtype_none', "k_classtype_none", "", 0),
816 ('k_classtype_gate', "k_classtype_gate", "", 1),
817 ('k_classtype_block', "k_classtype_block", "", 2),
818 ('k_classtype_spawn', "k_classtype_spawn", "", 3),
819 ('k_classtype_water', "k_classtype_water", "", 4),
820 ('k_classtype_car_path', "k_classtype_car_path", "", 5),
821 ('k_classtype_capsule', "k_classtype_capsule", "", 7 ),
822 ('k_classtype_route_node', "k_classtype_route_node", "", 8 ),
823 ('k_classtype_route', "k_classtype_route", "", 9 )
826 class CV_OBJ_PANEL(bpy
.types
.Panel
):
827 bl_label
="Entity Config"
828 bl_idname
="SCENE_PT_cv_entity"
829 bl_space_type
='PROPERTIES'
830 bl_region_type
='WINDOW'
834 active_object
= bpy
.context
.active_object
835 if active_object
== None: return
836 _
.layout
.prop( active_object
.cv_data
, "classtype" )
838 if active_object
.cv_data
.classtype
== 'k_classtype_gate':
839 _
.layout
.prop( active_object
.cv_data
, "target" )
841 mesh
= active_object
.data
842 _
.layout
.label( text
=F
"(i) Data is stored in {mesh.name}" )
843 _
.layout
.prop( mesh
.cv_data
, "v0" )
845 elif active_object
.cv_data
.classtype
== 'k_classtype_car_path' or \
846 active_object
.cv_data
.classtype
== 'k_classtype_route_node':
847 _
.layout
.prop( active_object
.cv_data
, "target" )
848 _
.layout
.prop( active_object
.cv_data
, "target1" )
850 elif active_object
.cv_data
.classtype
== 'k_classtype_route':
851 _
.layout
.prop( active_object
.cv_data
, "target" )
853 elif active_object
.cv_data
.classtype
== 'k_classtype_block':
854 mesh
= active_object
.data
856 _
.layout
.label( text
=F
"(i) Data is stored in {mesh.name}" )
857 _
.layout
.prop( mesh
.cv_data
, "v0" )
858 _
.layout
.prop( mesh
.cv_data
, "v1" )
859 _
.layout
.prop( mesh
.cv_data
, "v2" )
860 _
.layout
.prop( mesh
.cv_data
, "v3" )
861 elif active_object
.cv_data
.classtype
== 'k_classtype_capsule':
862 mesh
= active_object
.data
863 _
.layout
.label( text
=F
"(i) Data is stored in {mesh.name}" )
864 _
.layout
.prop( mesh
.cv_data
, "v0" )
866 class CV_INTERFACE(bpy
.types
.Panel
):
867 bl_idname
= "VIEW3D_PT_carve"
869 bl_space_type
= 'VIEW_3D'
870 bl_region_type
= 'UI'
871 bl_category
= "Carve"
873 def draw(_
, context
):
875 layout
.operator( "carve.compile_all" )
878 for col
in bpy
.data
.collections
["export"].children
:
879 write_model( col
.name
)
881 class CV_COMPILE(bpy
.types
.Operator
):
882 bl_idname
="carve.compile_all"
883 bl_label
="Compile All"
885 def execute(_
,context
):
887 #cProfile.runctx("test_compile()",globals(),locals(),sort=1)
888 #for col in bpy.data.collections["export"].children:
889 # write_model( col.name )
893 classes
= [CV_OBJ_SETTINGS
,CV_OBJ_PANEL
,CV_COMPILE
,CV_INTERFACE
,\
897 global cv_view_draw_handler
900 bpy
.utils
.register_class(c
)
902 bpy
.types
.Object
.cv_data
= bpy
.props
.PointerProperty(type=CV_OBJ_SETTINGS
)
903 bpy
.types
.Mesh
.cv_data
= bpy
.props
.PointerProperty(type=CV_MESH_SETTINGS
)
905 cv_view_draw_handler
= bpy
.types
.SpaceView3D
.draw_handler_add(\
906 cv_draw
,(),'WINDOW','POST_VIEW')
909 global cv_view_draw_handler
912 bpy
.utils
.unregister_class(c
)
914 bpy
.types
.SpaceView3D
.draw_handler_remove(cv_view_draw_handler
,'WINDOW')