mirror of
https://github.com/reanimate/reanimate.git
synced 2026-09-10 23:52:22 +00:00
Rewamp the scene api, add circle plots, add blender flips, fix caching issue in driver, fix bug in partialSvg. Former-commit-id: 5cb900521044fee13766dd7474fd9b72c7691686
200 lines
6 KiB
Haskell
Executable file
200 lines
6 KiB
Haskell
Executable file
{-# LANGUAGE OverloadedStrings #-}
|
|
{-# LANGUAGE QuasiQuotes #-}
|
|
{-# LANGUAGE RecordWildCards #-}
|
|
{-# LANGUAGE ApplicativeDo #-}
|
|
module Reanimate.Builtin.Flip
|
|
( FlipSprite(..)
|
|
, flipSprite
|
|
, Transition
|
|
, signalT
|
|
, flipTransition
|
|
, flipTransitionOpts
|
|
, overlapTransition
|
|
) where
|
|
|
|
import Reanimate.Animation
|
|
import Reanimate.Blender
|
|
import Reanimate.Raster
|
|
import Reanimate.Scene
|
|
import Reanimate.Signal
|
|
import Reanimate.Svg.Constructors
|
|
|
|
import Data.String.Here
|
|
import qualified Data.Text as T
|
|
|
|
data FlipSprite s = FlipSprite
|
|
{ fsSprite :: Sprite s
|
|
, fsBend :: Var s Double
|
|
, fsZoom :: Var s Double
|
|
, fsWobble :: Var s Double
|
|
}
|
|
|
|
flipSprite :: Animation -> Animation -> Scene s (FlipSprite s)
|
|
flipSprite front back = do
|
|
bend <- newVar 0
|
|
trans <- newVar 0
|
|
rotX <- newVar 0
|
|
s <- newSprite $ do
|
|
getBend <- unVar bend
|
|
getTrans <- unVar trans
|
|
getRotX <- unVar rotX
|
|
t <- spriteT
|
|
dur <- spriteDuration
|
|
return $
|
|
let rotY = fromToS 0 pi (t/dur)
|
|
frontTexture = svgAsPngFile (frameAt t $ setDuration dur front)
|
|
backTexture = svgAsPngFile (flipXAxis $ frameAt t $ setDuration dur back)
|
|
-- seq'ing frontTexture and backTexture is required to avoid segfaults. :(
|
|
in frontTexture `seq` backTexture `seq`
|
|
blender (script frontTexture backTexture getBend getTrans getRotX rotY)
|
|
return FlipSprite
|
|
{ fsSprite = s
|
|
, fsBend = bend
|
|
, fsZoom = trans
|
|
, fsWobble = rotX }
|
|
|
|
type Transition = Animation -> Animation -> Animation
|
|
|
|
signalT :: Signal -> Transition -> Transition
|
|
signalT s t = \a b -> signalA s (t a b)
|
|
|
|
overlapTransition :: Double -> Transition -> Transition
|
|
overlapTransition overlap t a b =
|
|
aBefore `seqA` t aOverlap bOverlap `seqA` bAfter
|
|
where
|
|
aBefore = takeA (duration a - overlap) a
|
|
aOverlap = dropA (duration a - overlap) a
|
|
bOverlap = takeA overlap b
|
|
bAfter = dropA overlap b
|
|
|
|
flipTransitionOpts :: Double -> Double -> Double -> Transition
|
|
flipTransitionOpts bend zoom wobble a b = sceneAnimation $ do
|
|
FlipSprite{..} <- flipSprite a b
|
|
fork $ tweenVar fsZoom dur $ \v -> fromToS v zoom . oscillateS
|
|
fork $ tweenVar fsBend dur $ \v -> fromToS v bend . oscillateS
|
|
fork $ tweenVar fsWobble dur $ \v -> fromToS v wobble . oscillateS
|
|
where
|
|
dur = max (duration a) (duration b)
|
|
|
|
flipTransition :: Transition
|
|
flipTransition = flipTransitionOpts bend zoom wobble
|
|
where
|
|
bend = 1/3
|
|
zoom = 3
|
|
wobble = -pi*0.10
|
|
|
|
script :: FilePath -> FilePath -> Double -> Double -> Double -> Double -> T.Text
|
|
script frontImage backImage bend transZ rotX rotY = [iTrim|
|
|
import os
|
|
import math
|
|
|
|
import bpy
|
|
|
|
light = bpy.data.objects['Light']
|
|
bpy.ops.object.select_all(action='DESELECT')
|
|
light.select_set(True)
|
|
bpy.ops.object.delete()
|
|
|
|
|
|
cam = bpy.data.objects['Camera']
|
|
cam.location = (0,0,22.22 + ${transZ})
|
|
cam.rotation_euler = (0, 0, 0)
|
|
bpy.ops.object.empty_add(location=(0.0, 0, 0))
|
|
focus_target = bpy.context.object
|
|
bpy.ops.object.select_all(action='DESELECT')
|
|
cam.select_set(True)
|
|
focus_target.select_set(True)
|
|
bpy.ops.object.parent_set()
|
|
|
|
focus_target.rotation_euler = (${rotX}, 0, 0)
|
|
|
|
|
|
origin = bpy.data.objects['Cube']
|
|
bpy.ops.object.select_all(action='DESELECT')
|
|
origin.select_set(True)
|
|
bpy.ops.object.delete()
|
|
|
|
x = ${bend}
|
|
bpy.ops.mesh.primitive_plane_add()
|
|
plane = bpy.context.object
|
|
plane.scale = (16/2,${fromToS (9/2) 4 bend},1)
|
|
bpy.ops.object.shade_smooth()
|
|
|
|
bpy.context.object.active_material = bpy.data.materials['Material']
|
|
mat = bpy.context.object.active_material
|
|
mix = mat.node_tree.nodes.new('ShaderNodeMixShader')
|
|
geo = mat.node_tree.nodes.new('ShaderNodeNewGeometry')
|
|
|
|
mat.blend_method = 'HASHED'
|
|
|
|
image_node = mat.node_tree.nodes.new('ShaderNodeTexImage')
|
|
gh_node = mat.node_tree.nodes.new('ShaderNodeTexImage')
|
|
output = mat.node_tree.nodes['Material Output']
|
|
|
|
gh_mix = mat.node_tree.nodes.new('ShaderNodeMixShader')
|
|
transparent = mat.node_tree.nodes.new('ShaderNodeBsdfTransparent')
|
|
|
|
mat.node_tree.links.new(geo.outputs['Backfacing'], mix.inputs['Fac'])
|
|
mat.node_tree.links.new(mix.outputs['Shader'], output.inputs['Surface'])
|
|
mat.node_tree.links.new(image_node.outputs['Color'], mix.inputs[1])
|
|
|
|
#mat.node_tree.links.new(gh_node.outputs['Color'], mix.inputs[2])
|
|
mat.node_tree.links.new(gh_node.outputs['Color'], gh_mix.inputs[2])
|
|
mat.node_tree.links.new(gh_node.outputs['Alpha'], gh_mix.inputs['Fac'])
|
|
mat.node_tree.links.new(transparent.outputs['BSDF'], gh_mix.inputs[1])
|
|
mat.node_tree.links.new(gh_mix.outputs['Shader'], mix.inputs[2])
|
|
|
|
image_node.image = bpy.data.images.load('${T.pack frontImage}')
|
|
image_node.interpolation = 'Closest'
|
|
|
|
gh_node.image = bpy.data.images.load('${T.pack backImage}')
|
|
gh_node.interpolation = 'Closest'
|
|
|
|
|
|
modifier = plane.modifiers.new(name='Subsurf', type='SUBSURF')
|
|
modifier.levels = 7
|
|
modifier.render_levels = 7
|
|
modifier.subdivision_type = 'SIMPLE'
|
|
|
|
bpy.ops.object.empty_add(type='ARROWS',rotation=(math.pi/2,0,0))
|
|
empty = bpy.context.object
|
|
|
|
bendUp = plane.modifiers.new(name='Bend up', type='SIMPLE_DEFORM')
|
|
bendUp.deform_method = 'BEND'
|
|
bendUp.origin = empty
|
|
bendUp.deform_axis = 'X'
|
|
bendUp.factor = -math.pi*x
|
|
|
|
bendAround = plane.modifiers.new(name='Bend around', type='SIMPLE_DEFORM')
|
|
bendAround.deform_method = 'BEND'
|
|
bendAround.origin = empty
|
|
bendAround.deform_axis = 'Z'
|
|
bendAround.factor = -math.pi*2*x
|
|
|
|
bpy.context.view_layer.objects.active = plane
|
|
bpy.ops.object.modifier_apply(modifier='Subsurf')
|
|
bpy.ops.object.modifier_apply(modifier='Bend up')
|
|
bpy.ops.object.modifier_apply(modifier='Bend around')
|
|
|
|
bpy.ops.object.select_all(action='DESELECT')
|
|
plane.select_set(True);
|
|
bpy.ops.object.origin_clear()
|
|
bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN')
|
|
|
|
plane.rotation_euler = (0, ${rotY}, 0)
|
|
|
|
scn = bpy.context.scene
|
|
|
|
#scn.render.engine = 'CYCLES'
|
|
#scn.render.resolution_percentage = 10
|
|
|
|
scn.view_settings.view_transform = 'Standard'
|
|
|
|
|
|
scn.render.resolution_x = 2560
|
|
scn.render.resolution_y = 1440
|
|
|
|
scn.render.film_transparent = True
|
|
|
|
bpy.ops.render.render( write_still=True )
|
|
|]
|