Add sunrise Threads automation and improve capture and character interactions
This commit is contained in:
+18
-11
@@ -1,5 +1,5 @@
|
||||
"""Run with Blender MCP. Separate cartoon rain gear for the rounded v10 sheep."""
|
||||
import bpy, bmesh, math, json, struct
|
||||
import bpy, bmesh, math, json, struct, sys
|
||||
from mathutils import Vector, Matrix
|
||||
ROOT='D:/project/sunrise'
|
||||
with bpy.data.libraries.load(ROOT+'/assets/characters/ivory-lamb-v10.blend',link=False) as (src,dst):
|
||||
@@ -54,27 +54,34 @@ def sphere(name,location,scale,mat,parent):
|
||||
|
||||
umbrella=empty('Umbrella')
|
||||
# The grip is in the raised right hoof; the tilted shaft centers the canopy above the head.
|
||||
grip=Vector((.58,-.40,.82)); top=Vector((0,-.05,3.03))
|
||||
grip=Vector((.58,-.40,.82)); top=Vector((0,-.05,3.18))
|
||||
stroke('Umbrella shaft',[grip,top],.022,ink,umbrella)
|
||||
def canopy_point(radius,sector,across):
|
||||
# Taut fabric curves inward between the eight projecting rib tips.
|
||||
scallop=math.sin(math.pi*across)
|
||||
r=1.20*radius*(1-.10*scallop*radius**3)
|
||||
a=(sector+across)*math.pi/4
|
||||
return (r*math.cos(a),-.05+r*math.sin(a),3.18-.65*radius**1.4+.10*scallop*radius**3)
|
||||
for sector in range(8):
|
||||
vertices=[];faces=[]
|
||||
for row in range(9):
|
||||
theta=(math.pi/2)*row/8
|
||||
for col in range(5):
|
||||
a=(sector+col/4)*math.pi/4
|
||||
vertices.append((1.28*math.sin(theta)*math.cos(a),-.05+1.28*math.sin(theta)*math.sin(a),2.53+.50*math.cos(theta)))
|
||||
vertices.append(canopy_point(row/8,sector,col/4))
|
||||
for row in range(8):
|
||||
for col in range(4):
|
||||
i=row*5+col;faces.append((i,i+1,i+6,i+5))
|
||||
panel=mesh('Canopy panel',vertices,faces,red if sector%2==0 else cream,umbrella)
|
||||
panel=mesh('Canopy panel',vertices,faces,red,umbrella)
|
||||
bpy.context.view_layer.objects.active=panel
|
||||
solid=panel.modifiers.new('Canopy thickness','SOLIDIFY');solid.thickness=.018
|
||||
bpy.ops.object.modifier_apply(modifier=solid.name)
|
||||
a=sector*math.pi/4
|
||||
stroke('Canopy rib',[(1.28*math.sin(t)*math.cos(a),-.05+1.28*math.sin(t)*math.sin(a),2.54+.50*math.cos(t)) for t in [i*math.pi/32 for i in range(17)]],.009,ink,umbrella)
|
||||
stroke('Canopy rim',[(1.28*math.cos(a),-.05+1.28*math.sin(a),2.53) for a in [i*math.tau/96 for i in range(97)]],.016,ink,umbrella)
|
||||
sphere('Umbrella tip',(0,-.05,3.055),(.04,.04,.07),ink,umbrella)
|
||||
stroke('Canopy rib',[canopy_point(i/16,sector,0) for i in range(17)],.009,ink,umbrella)
|
||||
stroke('Canopy rim',[canopy_point(1,sector,i/12) for i in range(13)],.012,ink,umbrella)
|
||||
sphere('Rib tip',canopy_point(1,sector,0),(.025,.025,.025),ink,umbrella)
|
||||
stroke('Umbrella tip',[(0,-.05,3.17),(0,-.05,3.33)],.022,ink,umbrella)
|
||||
sphere('Grip',grip,(.052,.052,.12),red,umbrella)
|
||||
stroke('Hook handle',[grip,(grip.x,grip.y,grip.z-.16)]+[
|
||||
(grip.x-.10+.10*math.cos(a),grip.y,grip.z-.16-.10*math.sin(a))
|
||||
for a in [i*math.pi/16 for i in range(17)]],.033,red,umbrella)
|
||||
|
||||
coat=empty('Raincoat')
|
||||
for joint_name in ('Body','ArmLeft','ArmRight'):
|
||||
@@ -174,6 +181,6 @@ def export(root,path):
|
||||
f.write(struct.pack('<III',0x46546C67,2,20+len(encoded)+len(binary)))
|
||||
f.write(struct.pack('<II',len(encoded),0x4E4F534A));f.write(encoded);f.write(binary)
|
||||
export(umbrella,ROOT+'/public/characters/umbrella.glb')
|
||||
export(coat,ROOT+'/public/characters/raincoat.glb')
|
||||
if '--umbrella-only' not in sys.argv:export(coat,ROOT+'/public/characters/raincoat.glb')
|
||||
bpy.data.libraries.write(ROOT+'/assets/characters/rain-gear.blend',{scene})
|
||||
print('Umbrella and articulated raincoat exported')
|
||||
|
||||
Reference in New Issue
Block a user