@震える
--track0:振幅,0,500,5
--track1:角度,0,180,10
--track2:間隔,0,100,0
if( obj.track2 == 0 ) then
	obj.ox = obj.ox+rand(-obj.track0,obj.track0,0)
	obj.oy = obj.oy+rand(-obj.track0,obj.track0,1)
	obj.rz = obj.rz+rand(-obj.track1,obj.track1,2)
else
	t = obj.time*100/obj.track2
	p = math.floor(t)
	t = t-p
	x0 = obj.rand(-1000,1000,0,p+0)/1000*obj.track0
	x1 = obj.rand(-1000,1000,0,p+1)/1000*obj.track0
	x2 = obj.rand(-1000,1000,0,p+2)/1000*obj.track0
	x3 = obj.rand(-1000,1000,0,p+3)/1000*obj.track0
	y0 = obj.rand(-1000,1000,1,p+0)/1000*obj.track0
	y1 = obj.rand(-1000,1000,1,p+1)/1000*obj.track0
	y2 = obj.rand(-1000,1000,1,p+2)/1000*obj.track0
	y3 = obj.rand(-1000,1000,1,p+3)/1000*obj.track0
	r0 = obj.rand(-1000,1000,2,p+0)/1000*obj.track1
	r1 = obj.rand(-1000,1000,2,p+1)/1000*obj.track1
	r2 = obj.rand(-1000,1000,2,p+2)/1000*obj.track1
	r3 = obj.rand(-1000,1000,2,p+3)/1000*obj.track1
	x,y = obj.interpolation(t,x0,y0,x1,y1,x2,y2,x3,y3)
	obj.ox = obj.ox + x
	obj.oy = obj.oy + y
	r = obj.interpolation(t,r0,r1,r2,r3)
	obj.rz = obj.rz + r
end

@振り子
--track0:速さ,0,10,2
--track1:角度,0,180,30
--track2:ずらし,0,100,0
obj.rz = obj.rz+math.sin((obj.time*obj.track0+obj.index*obj.track2/50)*math.pi)*obj.track1

@弾む
--track0:速さ,0.1,100,20
--track1:高さ,0,1000,150
--track2:角度,0,360,0
--track3:ずらし,0,100,0
l = math.floor((10/obj.track0)*obj.framerate)/obj.framerate;
n,l = math.modf(obj.time/l+obj.index*obj.track3/100)
l = (l-0.5)*2
l = (1-l*l)*obj.track1
r = obj.track2*math.pi/180
obj.ox = obj.ox+math.sin(r)*l
obj.oy = obj.oy-math.cos(r)*l

@座標の拡大縮小(個別オブジェクト)
--label:配置
--track0:拡大率,0,1000,100
--track1:中心X,-1000,1000,0
--track2:中心Y,-1000,1000,0
obj.ox = obj.track1+(obj.ox-obj.track1)*obj.track0/100
obj.oy = obj.track2+(obj.oy-obj.track2)*obj.track0/100

@画面外から登場
--label:切り替え効果
--track0:時間,-5,5,0.5
--track1:角度,-360,360,90
--track2:数,1,16,1,1
--check0:ランダム方向,0
if( obj.track0 == 0 ) then
	return
elseif( obj.track0 < 0 ) then
	t = (obj.track0-obj.time+obj.totaltime)/obj.track0
else
	t = (obj.track0-obj.time)/obj.track0
end
if( t > 0 ) then
	r = obj.track1
	if( obj.check0 ) then
		r = ( r + rand(0,360,obj.index,0) ) % 360
	end
	n = obj.track2
	l = math.sqrt(obj.screen_w*obj.screen_w+obj.screen_h*obj.screen_h)
	t = t*l
	l = l/(math.abs(obj.track0)*75)
	if( l > 100 ) then
		l = 100
	end
	if( n < 2 ) then
		obj.ox = obj.ox+math.sin(r*math.pi/180)*t
		obj.oy = obj.oy-math.cos(r*math.pi/180)*t
		if( l >= 1 ) then
			obj.effect("方向ブラー","角度",r,"範囲",l)
		end
	else
		ox = obj.ox; -- load()でパラメータが初期値になってしまうので…
		oy = obj.oy
		oz = obj.oz
		if( l >= 1 ) then
			obj.copybuffer("tmp","obj")
		end
		for i=1,n do
			if( l >= 1 ) then
				obj.load("tempbuffer")
			end
			obj.ox = ox+math.sin(r*math.pi/180)*t
			obj.oy = oy-math.cos(r*math.pi/180)*t
			obj.oz = oz
			if( l >= 1 ) then
				obj.effect("方向ブラー","角度",r,"範囲",l)
			end
			obj.draw()
			if( obj.check0 ) then
				r = ( r + rand(0,360,obj.index,i) ) % 360
			else
				r = ( r + 360/n ) % 360
			end
		end
	end
end

@ランダム方向から登場
--label:切り替え効果
--track0:時間,-5,5,1.5
--track1:回転,0,10,3
--track2:ライト,0,100,30
--check0:加減速,1
if( obj.track0 == 0 ) then
	return
elseif( obj.track0 < 0 ) then
	t = (obj.track0-obj.time+obj.totaltime)/obj.track0
else
	t = (obj.track0-obj.time)/obj.track0
end
if( t > 0 ) then
	if( obj.check0 ) then
		t = t*t
	end
	r = t
	if( rand(0,1,obj.index,0) == 0 ) then r = -r end
	obj.rx = obj.rx+rand(90,360,obj.index,0)*r*obj.track1
	if( rand(0,1,obj.index,1) == 0 ) then r = -r end
	obj.ry = obj.ry+rand(90,360,obj.index,1)*r*obj.track1
	if( rand(0,1,obj.index,2) == 0 ) then r = -r end
	obj.rz = obj.rz+rand(90,360,obj.index,2)*r*obj.track1*2
	r = rand(0,360,obj.index,0)
	l = math.sqrt(obj.screen_w*obj.screen_w+obj.screen_h*obj.screen_h)
	l = l*t
	obj.ox = obj.ox+math.sin(r)*l
	obj.oy = obj.oy-math.cos(r)*l
	obj.zoom = obj.zoom*(1+t)
	r = math.abs( math.cos((obj.rx-45)*math.pi/180)*math.cos((obj.ry+45)*math.pi/180) )
	if( r > 0.5 ) then
		l = 100+(r-0.5)*2*obj.track2
		r = r*r
		if( r > 0.9 ) then
			l = l + (r-0.9)*20*obj.track2
		end
	else
		l = 100-(0.5-r)*2*obj.track2
	end
	obj.effect("色調補正","明るさ",l)
end

@拡大縮小して登場
--label:切り替え効果
--track0:時間,-5,5,0.3
--track1:拡大率,0,800,300
--check0:加減速,1
if( obj.track0 == 0 ) then
	return
elseif( obj.track0 < 0 ) then
	t = (obj.track0-obj.time+obj.totaltime)/obj.track0
else
	t = (obj.track0-obj.time)/obj.track0
end
if( t > 0 ) then
	obj.alpha = math.cos(t*math.pi/2)
	if( obj.check0 ) then
		t = t*t
	end
	obj.zoom = obj.zoom*( 1 + (obj.track1-100)*t/100 )
end

@ランダム間隔で落ちながら登場
--label:切り替え効果
--track0:時間,-5,5,0.5
--track1:間隔,0,5,1
--track2:距離,0,1000,400
--check0:加減速,1
if( obj.track0 == 0 ) then
	return
elseif( obj.track0 < 0 ) then
	t = (obj.track0-obj.time+obj.totaltime-rand(0,100,obj.index,0)*obj.track1/100)/obj.track0
	v = obj.track2
else
	t = (obj.track0-obj.time+rand(0,100,obj.index,0)*obj.track1/100)/obj.track0
	v = -obj.track2
end
if( t > 0 ) then
	if( obj.check0 ) then
		t = t*t
	end
	obj.alpha = math.cos(t*math.pi/2)
	obj.oy = obj.oy+v*t
end

@弾んで登場
--label:切り替え効果
--track0:時間,-5,5,2
--track1:高さ,-1000,1000,200
--track2:回数,1,20,4
n = obj.track2;
t = math.floor(obj.track0*obj.framerate/n)
t = t*n/obj.framerate
if( t == 0 ) then
	return
elseif( t < 0 ) then
	t = (obj.track0-obj.time+obj.totaltime)/t
	v = -1
else
	t = (obj.track0-obj.time)/t
	v = 1
end
if( t >= 0 ) then
	x = math.sqrt(obj.screen_w*obj.screen_w+obj.screen_h*obj.screen_h)*t*v
	obj.ox = obj.ox + x
	n,y = math.modf(t*n)
	y = (y-0.5)*2
	y = (1-y*y)*obj.track1
	obj.oy = obj.oy - y
end

@広がって登場
--label:切り替え効果
--track0:時間,-5,5,0.3
--check0:縦方向,0
if( obj.track0 == 0 ) then
	return
elseif( obj.track0 < 0 ) then
	t = (obj.track0-obj.time+obj.totaltime)/obj.track0
else
	t = (obj.track0-obj.time)/obj.track0
end
if( t > 0 ) then
	t = t*t
	if( obj.check0 ) then
		obj.aspect = -t
	else
		obj.aspect = t
	end
end

@起き上がって登場
--label:切り替え効果
--track0:時間,-5,5,0.6
--track1:勢い,0,8,2.0
if( obj.track0 == 0 ) then
	return
elseif( obj.track0 < 0 ) then
	t = (obj.track0-obj.time+obj.totaltime)/obj.track0
else
	t = (obj.track0-obj.time)/obj.track0
end
if( t >= 0 ) then
	n = obj.track1*2+1
	if( n <= 1 ) then
		t = t*t
	elseif( t > 1-1/n ) then
		t = 1-(1-t)*n
	else
		t = t*n/(n-1)
		t = math.sin((t-1)*(n-1)*math.pi)*t*0.4/(1+(1-t)*3)
	end
	obj.rx = obj.rx - 90*t
	obj.oy = obj.oy + obj.h*(1-math.cos(t*math.pi/2))/2
	obj.oz = obj.oz + obj.h*math.sin(t*math.pi/2)/2
end

@何処からともなく登場
--label:切り替え効果
--track0:時間,-5,5,0.3
--track1:ぼかし,0,5,1.0
--track2:位置,0,5,1.5
if( obj.track0 == 0 ) then
	return
elseif( obj.track0 < 0 ) then
	t = (obj.track0-obj.time+obj.totaltime)/obj.track0
else
	t = (obj.track0-obj.time)/obj.track0
end
if( t > 0 ) then
	obj.ox = obj.ox+rand(-obj.w*obj.track2/2,obj.w*obj.track2/2,obj.index+100)
	obj.oy = obj.oy+rand(-obj.h*obj.track2/2,obj.h*obj.track2/2,obj.index+200)
	obj.alpha = rand(0,100,obj.index+300)/100
	if( rand(0,1,obj.index+400) == 0 ) then
		obj.aspect = -(0.5+rand(0,40,obj.index+500)/100)
		obj.effect("ぼかし","縦横比",90,"範囲",obj.track1*obj.w)
	else
		obj.aspect = 0.5+rand(0,40,obj.index+500)/100
		obj.effect("ぼかし","縦横比",-90,"範囲",obj.track1*obj.h)
	end
	obj.effect("色調補正","明るさ",rand(100,200,obj.index+600))
end

@反復移動
--track0:速さ,0.1,100,20
--track1:距離,0,1000,100
--track2:角度,0,360,0
--track3:ずらし,0,100,0
l = math.sin((obj.time*obj.track0+obj.index*obj.track3/5)*math.pi/10)*obj.track1
r = obj.track2*math.pi/180
obj.ox = obj.ox+math.sin(r)*l
obj.oy = obj.oy-math.cos(r)*l

@座標の回転(個別オブジェクト)
--label:配置
--track0:角度,-360,360,0
--track1:中心X,-1000,1000,0
--track2:中心Y,-1000,1000,0
x = obj.ox-obj.track1
y = obj.oy-obj.track2
r = obj.track0*math.pi/180
obj.ox = obj.track1+x*math.cos(r)-y*math.sin(r)
obj.oy = obj.track2+x*math.sin(r)+y*math.cos(r)

@立方体(カメラ制御)
--label:変形
--track0:サイズ,0,2000,200
obj.effect()
l = obj.track0*obj.getvalue("zoom")/100
local vertex={}
table.insert(vertex,{-l,-l,-l,  l,-l,-l,  l, l,-l, -l, l,-l, 0,0, obj.w,0, obj.w,obj.h, 0,obj.h})
table.insert(vertex,{ l,-l, l, -l,-l, l, -l, l, l,  l, l, l, 0,0, obj.w,0, obj.w,obj.h, 0,obj.h})
table.insert(vertex,{-l, l,-l,  l, l,-l,  l, l, l, -l, l, l, 0,0, obj.w,0, obj.w,obj.h, 0,obj.h})
table.insert(vertex,{ l,-l,-l, -l,-l,-l, -l,-l, l,  l,-l, l, 0,0, obj.w,0, obj.w,obj.h, 0,obj.h})
table.insert(vertex,{ l,-l,-l,  l,-l, l,  l, l, l,  l, l,-l, 0,0, obj.w,0, obj.w,obj.h, 0,obj.h})
table.insert(vertex,{-l,-l, l, -l,-l,-l, -l, l,-l, -l, l, l, 0,0, obj.w,0, obj.w,obj.h, 0,obj.h})
obj.drawpoly(vertex)
obj.setoption("focus_mode","fixed_size")

@球体(カメラ制御)
--label:変形
--track0:サイズ,0,2000,200
obj.effect()
obj.setoption('antialias',0);
r = obj.track0*obj.getvalue("zoom")/100
w = 50
h = 50
local vertex={}
for y=0,h-1 do
	y0 = -r*math.cos(math.pi*y    /h)
	r0 =  r*math.sin(math.pi*y    /h)
	y1 = -r*math.cos(math.pi*(y+1)/h)
	r1 =  r*math.sin(math.pi*(y+1)/h)
	v0 = obj.h*y    /h;
	v1 = obj.h*(y+1)/h;
	for x=0,w-1 do
		x0 =  r0*math.sin(math.pi*2*x    /w)
		x1 =  r0*math.sin(math.pi*2*(x+1)/w)
		x2 =  r1*math.sin(math.pi*2*(x+1)/w)
		x3 =  r1*math.sin(math.pi*2*x    /w)
		z0 = -r0*math.cos(math.pi*2*x    /w)
		z1 = -r0*math.cos(math.pi*2*(x+1)/w)
		z2 = -r1*math.cos(math.pi*2*(x+1)/w)
		z3 = -r1*math.cos(math.pi*2*x    /w)
		u0 = obj.w*x    /w;
		u1 = obj.w*(x+1)/w;
		table.insert(vertex,{x0,y0,z0,x1,y0,z1,x2,y1,z2,x3,y1,z3,u0,v0,u1,v0,u1,v1,u0,v1,x0,y0,z0,x1,y0,z1,x2,y1,z2,x3,y1,z3})
	end
end
obj.drawpoly(vertex); -- 纏めて描画
obj.setoption("focus_mode","fixed_size")

@砕け散る
--track0:開始時間,-100,100,0,0.01
--track@step:再生速度,-10,10,1,0.01
--track1:中心X,-5000,5000,0
--track2:中心Y,-5000,5000,0
--track3:中心Z,-5000,5000,0
--track@size:破片サイズ,5,1000,50
--track@speed:速度,-5000,5000,100
--track@grav:重力,0,1000,100
--track@delay:時間差,-1000,1000,100
--track@impact:距離影響,0,5000,100
--track@spin:ランダム回転,0,5000,100
--track@diff:ランダム方向,0,5000,100
local px={}
local py={}
local pz={}
local pu={}
local pv={}
if( step < 0 ) then 
	tm = obj.time*step+obj.track0
else
	tm = obj.time*step-obj.track0
end
if( tm < 0 ) then
	return
end
obj.effect()
grav = grav*6
delay = delay*0.002
impact = impact*0.1
spin = math.floor(spin*10)
diff = diff/80
if( size < 5 ) then
	size = 5
end 
xl = obj.w
yl = obj.h
ax = obj.track1
ay = obj.track2
az = obj.track3
sp = speed*0.01*math.sqrt(impact)
w = math.floor(xl/size)
h = math.floor(yl/size)
l = math.sqrt(xl*xl+yl*yl)
if( w < 2 ) then
	w = 2
elseif( w > xl ) then
	w = xl
end
if( h < 2 ) then
	h = 2
elseif( h > yl ) then
	h = yl
end
pw = xl/w/2.3
ph = yl/h/2.3
local vertex={}
for y=0,h-1 do
	for x=0,w-1 do
		-- 各頂点を計算
		pu[0] = xl*x/w
		pu[1] = xl*(x+1)/w
		pu[2] = pu[1]
		pu[3] = pu[0]
		pv[0] = yl*y/h
		pv[1] = pv[0]
		pv[2] = yl*(y+1)/h
		pv[3] = pv[2]
		pu[0] = pu[0] + obj.rand(-pw,pw,x  ,y  )
		pu[1] = pu[1] + obj.rand(-pw,pw,x+1,y  )
		pu[2] = pu[2] + obj.rand(-pw,pw,x+1,y+1)
		pu[3] = pu[3] + obj.rand(-pw,pw,x  ,y+1)
		pv[0] = pv[0] + obj.rand(-ph,ph,x  ,y  +1000)
		pv[1] = pv[1] + obj.rand(-ph,ph,x+1,y  +1000)
		pv[2] = pv[2] + obj.rand(-ph,ph,x+1,y+1+1000)
		pv[3] = pv[3] + obj.rand(-ph,ph,x  ,y+1+1000)
		if( x == 0 ) then
			pu[0] = 0
			pu[3] = 0
		elseif ( x == w-1 ) then
			pu[1] = xl
			pu[2] = xl
		end
		if( y == 0 ) then
			pv[0] = 0
			pv[1] = 0
		elseif ( y == h-1 ) then
			pv[2] = yl
			pv[3] = yl
		end
		-- 基準の計算
		gx = (pu[0]+pu[1]+pu[2]+pu[3])/4
		gy = (pv[0]+pv[1]+pv[2]+pv[3])/4
		gz = 0
		cx = gx-xl/2
		cy = gy-yl/2
		cz = 0
		vx = cx-ax
		vy = cy-ay
		vz = -az
		v = math.sqrt(vx*vx+vy*vy+vz*vz)
		-- 時間の計算
		t = tm-v/l*delay
		if( t < 0 ) then
			t = 0
		end
		-- 回転を計算
		xx = t*obj.rand(-spin,spin,x,y+2000)/100
		yy = t*obj.rand(-spin,spin,x,y+3000)/100
		zz = t*obj.rand(-spin,spin,x,y+4000)/100
		sin_x = math.sin(xx);
		cos_x = math.cos(xx);
		sin_y = math.sin(yy);
		cos_y = math.cos(yy);
		sin_z = math.sin(zz);
		cos_z = math.cos(zz);
		m00 =  cos_y*cos_z
		m01 = -cos_y*sin_z
		m10 =  cos_x*sin_z +sin_x*cos_z*sin_y
		m11 =  cos_x*cos_z -sin_x*sin_z*sin_y
		m20 =  sin_x*sin_z -cos_x*cos_z*sin_y
		m21 =  sin_x*cos_z +cos_x*sin_z*sin_y
		for i=0,3 do
			xx = pu[i]-gx
			yy = pv[i]-gy
			px[i] = m00*xx + m01*yy
			py[i] = m10*xx + m11*yy
			pz[i] = m20*xx + m21*yy
		end
		-- 表示座標を計算
		v = 1/(1+v*v/(l*l)*impact)
		vx = vx*v + obj.rand(-size,size,x,y+4000)*diff
		vy = vy*v + obj.rand(-size,size,x,y+5000)*diff
		vz = vz*v + obj.rand(-size,size,x,y+6000)*diff
		cx = cx + t*vx*sp
		cy = cy + t*vy*sp + t*t*grav
		cz = cz + t*vz*sp
		table.insert(vertex,{px[0]+cx,py[0]+cy,pz[0]+cz,px[1]+cx,py[1]+cy,pz[1]+cz,px[2]+cx,py[2]+cy,pz[2]+cz,px[3]+cx,py[3]+cy,pz[3]+cz, pu[0],pv[0],pu[1],pv[1],pu[2],pv[2],pu[3],pv[3]})
	end
end
obj.drawpoly(vertex); -- 纏めて描画

@点滅
--track0:速さ,0,15,1,0.01
--track1:点滅割合,0,100,50
--track2:点灯速度,0,100,100
--track3:消灯速度,0,100,75
l = math.floor(obj.framerate/obj.track0+0.5)
l0 = math.floor(l*(100-obj.track1)/100)
l1 = math.floor(l*obj.track1/100)
if( l0 < 1 ) then
	l0 = 1
end
if( l1 < 1 ) then
	l1 = 1
end
l0 = l0/obj.framerate
l1 = l1/obj.framerate
l = l0+l1
t = (obj.time+0.0001)%l
if( t < l1 ) then
	l = l1*(100-obj.track2)/100
	t = t+1/obj.framerate
	if( t < l ) then
		obj.alpha = obj.alpha*t/l
	end
else
	t = t-l1
	l = l0*(100-obj.track3)/100
	t = t+1/obj.framerate
	if( t < l ) then
		obj.alpha = obj.alpha*(1-t/l)
	else
		obj.alpha = 0
	end
end

@点滅して登場
--label:切り替え効果
--track0:時間,-5,5,1
--track1:点滅間隔,1,5,1,1
--check0:点滅間隔を一定にする,0
if( obj.track0 == 0 ) then
	return
elseif( obj.track0 < 0 ) then
	t = (obj.track0-obj.time+obj.totaltime)/obj.track0
else
	t = (obj.track0-obj.time)/obj.track0
end
l = obj.framerate*obj.track0/obj.track1
if( t > 0 ) then
	if( obj.check0 ) then
		t = t-0.0001
		if( (math.floor(t*l)%2) ~= 0 ) then
			obj.alpha = 0;
		end
	else
		t = 1-t+0.0001
		s = t*t/2
		t = t+1/l
		e = t*t/2
		if( math.floor(s*l) == math.floor(e*l) ) then
			obj.alpha = 0;
		end
	end
end

@簡易変形
--label:変形
--track0:時間経過,0,100,0
--dialog:座標,pos={-100,-100,100,-100,100,100,-100,100};分割数,div=30;
if( obj.getoption("track_mode",0) == 0 ) then
	obj.setanchor("pos",4,"loop")
else
	obj.setanchor("pos",8,"loop","inout")
	s = obj.track0/100
	for i=1,8 do
		pos[i] = pos[i] + (pos[i+8]-pos[i])*s
	end
end
if( div < 1  ) then div = 1  end
if( div > 50 ) then div = 50 end

-- 仮想バッファの解像度を決める
sx = math.min(pos[1],pos[3],pos[5],pos[7])
ex = math.max(pos[1],pos[3],pos[5],pos[7])
sy = math.min(pos[2],pos[4],pos[6],pos[8])
ey = math.max(pos[2],pos[4],pos[6],pos[8])
w = math.ceil(ex-sx)
h = math.ceil(ey-sy)
sx = (sx+ex)/2
sy = (sy+ey)/2
for i=0,3 do
	s = i*2+1
	pos[s  ] = pos[s  ] - sx
	pos[s+1] = pos[s+1] - sy
end
obj.setoption("drawtarget","tempbuffer",w,h)

-- 変形させて描画する
w,h = obj.getpixel()
px0 = pos[1]
py0 = pos[2]
px1 = pos[3]
py1 = pos[4]
px2 = pos[5]
py2 = pos[6]
px3 = pos[7]
py3 = pos[8]
sx1 = px0
sy1 = py0
ex1 = px1
ey1 = py1
v1 = 0
local vertex={}
for y=1,div do
	sx0 = sx1
	sy0 = sy1
	ex0 = ex1
	ey0 = ey1
	sx1 = px0+(px3-px0)*y/div
	sy1 = py0+(py3-py0)*y/div
	ex1 = px1+(px2-px1)*y/div
	ey1 = py1+(py2-py1)*y/div
	v0 = v1
	v1 = y*h/div
	x1 = sx0
	y1 = sy0
	x2 = sx1
	y2 = sy1
	u1 = 0
	for x=1,div do
		x0 = x1
		y0 = y1
		x1 = sx0+(ex0-sx0)*x/div
		y1 = sy0+(ey0-sy0)*x/div
		x3 = x2
		y3 = y2
		x2 = sx1+(ex1-sx1)*x/div
		y2 = sy1+(ey1-sy1)*x/div
		u0 = u1
		u1 = x*w/div
		table.insert(vertex,{x0,y0,0,x1,y1,0,x2,y2,0,x3,y3,0 ,u0,v0,u1,v0,u1,v1,u0,v1})
	end
end
obj.drawpoly(vertex);
obj.load("tempbuffer")
obj.cx = obj.cx - sx
obj.cy = obj.cy - sy
obj.setoption("focus_mode","fixed_size")

@簡易変形(カメラ制御)
--label:変形
--track0:時間経過,0,100,0
--dialog:座標,pos={-100,-100,0,100,-100,0,100,100,0,-100,100,0};分割数,div=30;
if( obj.getoption("track_mode",0) == 0 ) then
	obj.setanchor("pos",4,"loop","xyz")
else
	obj.setanchor("pos",8,"loop","xyz","inout")
	s = obj.track0/100
	for i=1,12 do
		pos[i] = pos[i] + (pos[i+12]-pos[i])*s
	end
end
if( div < 1  ) then div = 1  end
if( div > 50 ) then div = 50 end

-- 変形させて描画する
w = obj.w
h = obj.h
--zoom = obj.getvalue("zoom")*0.01
zoom = 1.0; -- 現実装ではdrawpoly()で拡大率が反映される
px0 = pos[1]*zoom
py0 = pos[2]*zoom
pz0 = pos[3]
px1 = pos[4]*zoom
py1 = pos[5]*zoom
pz1 = pos[6]
px2 = pos[7]*zoom
py2 = pos[8]*zoom
pz2 = pos[9]
px3 = pos[10]*zoom
py3 = pos[11]*zoom
pz3 = pos[12]
sx1 = px0
sy1 = py0
sz1 = pz0
ex1 = px1
ey1 = py1
ez1 = pz1
v1 = 0
local vertex={}
for y=1,div do
	sx0 = sx1
	sy0 = sy1
	sz0 = sz1
	ex0 = ex1
	ey0 = ey1
	ez0 = ez1
	sx1 = px0+(px3-px0)*y/div
	sy1 = py0+(py3-py0)*y/div
	sz1 = pz0+(pz3-pz0)*y/div
	ex1 = px1+(px2-px1)*y/div
	ey1 = py1+(py2-py1)*y/div
	ez1 = pz1+(pz2-pz1)*y/div
	v0 = v1
	v1 = y*h/div
	x1 = sx0
	y1 = sy0
	z1 = sz0
	x2 = sx1
	y2 = sy1
	z2 = sz1
	u1 = 0
	for x=1,div do
		x0 = x1
		y0 = y1
		z0 = z1
		x1 = sx0+(ex0-sx0)*x/div
		y1 = sy0+(ey0-sy0)*x/div
		z1 = sz0+(ez0-sz0)*x/div
		x3 = x2
		y3 = y2
		z3 = z2
		x2 = sx1+(ex1-sx1)*x/div
		y2 = sy1+(ey1-sy1)*x/div
		z2 = sz1+(ez1-sz1)*x/div
		u0 = u1
		u1 = x*w/div
		table.insert(vertex,{x0,y0,z0,x1,y1,z1,x2,y2,z2,x3,y3,z3 ,u0,v0,u1,v0,u1,v1,u0,v1})
	end
end
obj.drawpoly(vertex)
obj.setoption("focus_mode","fixed_size")

@リール回転
--track0:回転数,-50,50,0,1
--track1:ブラー,0,200,100
--check0:横回転,0
--filter
t = obj.time/obj.totaltime
t = -math.cos(math.pi*t)
b = 1-math.abs(t)
b = 2*b*b*obj.track1/100/obj.totalframe
if( t < 0 ) then
	t = (t+1)*(t+1)-1
else
	t = 1-(1-t)*(1-t)
end
vx = obj.track0
if( vx == 0 ) then
	vx = obj.totaltime*2
	if( obj.check0 ) then
		vx = -vx
	end
end
t = t*math.floor(math.abs(vx)+0.5)
b = b*math.floor(math.abs(vx)+0.5)
if( vx < 0 ) then
	vx = -1
else
	vx = 1;
end
if( obj.check0 ) then
	vy = 0
else
	vy = vx
	vx = 0
end
x = math.fmod(t,1)
if( x < 0 ) then
	x = x+1
end

w,h = obj.getpixel();
obj.setoption("drawtarget","tempbuffer",w,h);
obj.setoption('antialias',0)
obj.draw(vx*x    *obj.w,vy*x    *obj.h,0)
obj.draw(vx*(x-1)*obj.w,vy*(x-1)*obj.h,0)
obj.setoption('antialias',1)
obj.load("tempbuffer")
if( obj.check0 ) then
	obj.effect("ぼかし","サイズ固定",1,"縦横比",100,"範囲",b*w)
else
	obj.effect("ぼかし","サイズ固定",1,"縦横比",-100,"範囲",b*h)
end

@万華鏡
--label:変形
--track0:中心X,-1000,1000,0
--track1:中心Y,-1000,1000,0
--track2:長さ,0,2000,100
--track3:回転,-3600,3600,0
--track@num:角数(偶数),4,50,6,1
--track@ln:繰り返し回数,0,50,2,1
--track@size:固定サイズ,0,4000,0
--check@mask:円形マスク,0
--check@rsync:回転同期,0
--check@transparent:領域外を透過,false
--check0:表示位置確認,0
x = obj.track0
y = obj.track1
l = obj.track2
r = obj.track3*math.pi/180
ln = math.floor(ln)
if( ln < 0 ) then
	ln = 0
end
if( ln > 50 ) then
	ln = 50
end
num = math.floor(num)
num = num-AND(num,1)
if( num < 4 ) then
	num = 4
end
if( num > 50 ) then
	num = 50
end
if( size > 4000 ) then
	size = 4000
end

-- 回転用に配列にいれる
local u={}
local v={}
w,h = obj.getpixel()
u[1] = x+w/2
v[1] = y+h/2
u[2] = x+w/2+math.sin(r+math.pi*5/6)*l
v[2] = y+h/2-math.cos(r+math.pi*5/6)*l
u[3] = x+w/2+math.sin(r+math.pi*7/6)*l
v[3] = y+h/2-math.cos(r+math.pi*7/6)*l
u[4] = u[1]
v[4] = v[1]
u[5] = u[2]
v[5] = v[2]
if( size > 0 ) then
	l = size/(ln+1)/2
end
if( l <= 0 ) then
	obj.alpha = 0
	return
end
ll = l*math.sin(math.pi/num)*2

if( obj.getoption("gui") ) then
	if( obj.check0 ) then
		pos = {}
		pos[1] = u[1]-w/2
		pos[2] = v[1]-h/2
		pos[3] = u[2]-w/2
		pos[4] = v[2]-h/2
		pos[5] = u[3]-w/2
		pos[6] = v[3]-h/2
		obj.setanchor(pos,3,"loop")
		return
	end
end

-- 仮想バッファを作成
h = math.ceil((ln+1)*l*math.cos(math.pi/num))*2
if( AND(num,2) == 0 ) then
	w = h
else
	w = math.ceil((ln+1)*l)*2
end
obj.setoption("drawtarget","tempbuffer",w,h)

-- 角度毎に描画
local vertex={}
for ri=0,num-1 do
	rr = ri*math.pi*2/num
	dx0 =  math.sin(rr+math.pi+math.pi/num)*l
	dy0 = -math.cos(rr+math.pi+math.pi/num)*l
	dx1 =  math.sin(rr+math.pi/2)*ll
	dy1 = -math.cos(rr+math.pi/2)*ll
	for li=0,ln do
		x0 = li*dx0
		y0 = li*dy0
		x1 = x0+dx0
		y1 = y0+dy0
		x2 = x1+dx1
		y2 = y1+dy1
		td = 1-SHIFT(AND(ri,1),1)
		tr = li*td
		for ci=0,li*2 do
			p0 = ((tr+td*0)%3)+1
			p1 = ((tr+td*1)%3)+1
			p2 = ((tr+td*2)%3)+1
			table.insert(vertex,{x0,y0,0,x1,y1,0,x2,y2,0,x2,y2,0,u[p0],v[p0],u[p1],v[p1],u[p2],v[p2],u[p2],v[p2]})
			if( AND(ci,1)==0 ) then
				x1 = x0+dx1
				y1 = y0+dy1
			else
				x0 = x1
				y0 = y1
				x1 = x2
				y1 = y2
				x2 = x2+dx1
				y2 = y2+dy1
				tr = tr+td
			end
		end
	end
end
if( transparent ) then
	obj.setoption("sampler","clip")
end
obj.drawpoly(vertex)
obj.setoption("sampler")
obj.load("tempbuffer")
if( mask ~= 0 ) then
	obj.effect("マスク","サイズ",h,"type",1)
end
if( rsync ~= 0 ) then
	obj.rz = obj.rz+r*180/math.pi
end

@円形配置
--label:配置
--track0:円周,0,800,100,0.01
--track1:半径,-2000,2000,100
--track2:回転,-3600,3600,0
--track3:ずらし,-2000,2000,0
--track@num:数,1,500,8,1
--check0:水平配置(カメラ制御),0
--check@dir:向き反転,0
--check@rot:回転無し,0
if( obj.getoption("multi_object") ) then
	-- 個別オブジェクト
	if( obj.num > 0 ) then
		w = obj.num*obj.screen_w/20
	else
		w = obj.screen_w/2
	end
	if( obj.check0 ) then
		x = obj.ox
		y = 0
	else
		x = obj.ox
		y = obj.oy
		if( dir ~= 0 ) then
			y = -y
		end
	end
	r = (x*obj.track0/(w*50) + obj.track2/180)*math.pi
	x =  math.sin(r)*(-y+obj.track1)
	y = -math.cos(r)*(-y+obj.track1)
	if( dir == 0 ) then
		r = r*180/math.pi
	else
		y = -y
		r = -r*180/math.pi
	end
	obj.ox = x
	if( obj.check0 ) then
		obj.oy = obj.oy + obj.track3*r/360
		obj.oz = y
		if( rot == 0 ) then
			obj.ry = obj.ry-r
		end
	else
		obj.oy = y
		obj.oz = obj.track3*r/360
		if( rot == 0 ) then
			obj.rz = obj.rz+r
		end
	end
	obj.setoption("focus_mode","fixed_size")
	return
end
-- 通常オブジェクト
obj.effect()
for i=1,num do
	x = 0
	y = 0
	z = 0
	ry = 0
	rz = 0
	r = ((i-(num+1)/2)*obj.track0/50/num + obj.track2/180)*math.pi
	x =  math.sin(r)*obj.track1
	y = -math.cos(r)*obj.track1
	if( dir == 0 ) then
		r = r*180/math.pi
	else
		y = -y
		r = -r*180/math.pi
	end
	if( obj.check0 ) then
		z = y
		y = obj.track3*r/360
		if( rot == 0 ) then
			ry = ry-r
		end
	else
		z = obj.track3*r/360
		if( rot == 0 ) then
			rz = rz+r
		end
	end
	obj.draw(x,y,z,1,1,0,ry,rz)
end
obj.setoption("focus_mode","fixed_size")

@ランダム配置
--label:配置
--track0:数,0,4000,50,1
--track1:範囲,0,20000,800,0.1
--track2:回転,0,20,0,0.01
--track3:拡散,0,20000,0,0.1
--check0:3D配置(カメラ制御),0
--check@ang:ランダム角度,0
--check@bb:カメラの方向を向く,0
obj.effect()
num = obj.track0
l = obj.track1/2
r = obj.track2
a = obj.track3
if( obj.getoption("multi_object") ) then
	start = obj.index+1
	step  = obj.num
	if( start > num ) then
		obj.setoption("draw_state",true)
		return
	end
	obj.ox = 0
	obj.oy = 0
	obj.oz = 0
else
	start = 1
	step  = 1
end
if( bb == 1 ) then
	obj.setoption("billboard",3)
end
if( obj.check0 ) then
	for i=start,num,step do
		x = obj.rand(-10000,10000,i,10)*l/10000
		y = obj.rand(-10000,10000,i,11)*l/10000
		z = obj.rand(-10000,10000,i,12)*l/10000
		if( a > 0 ) then
			x = x+obj.rand(-10000,10000,i,20)*a/10000
			y = y+obj.rand(-10000,10000,i,21)*a/10000
			z = z+obj.rand(-10000,10000,i,22)*a/10000
		end
		if( ang == 1 ) then 
			rx = obj.rand(0,360,i,30)
			ry = obj.rand(0,360,i,31)
			rz = obj.rand(0,360,i,32)
		else
			rx,ry,rz = 0,0,0
		end
		if( r > 0 ) then
			rx = rx + obj.time*obj.rand(0,3600,i,40)*r/100
			ry = ry + obj.time*obj.rand(0,3600,i,41)*r/100
			rz = rz + obj.time*obj.rand(0,3600,i,42)*r/100
		end
		obj.draw(x,y,z,1,1,rx,ry,rz)
	end
else
	for i=start,num,step do
		x = obj.rand(-10000,10000,i,10)*l/10000
		y = obj.rand(-10000,10000,i,11)*l/10000
		if( a > 0 ) then
			x = x+obj.rand(-10000,10000,i,20)*a/10000
			y = y+obj.rand(-10000,10000,i,21)*a/10000
		end
		if( ang == 1 ) then 
			rz = obj.rand(0,360,i,32)
		else
			rz = 0,0,0
		end
		if( r > 0 ) then
			rz = rz + obj.time*obj.rand(0,3600,i,42)*r/100
		end
		obj.draw(x,y,0,1,1,0,0,rz)
	end
end
obj.setoption("focus_mode","fixed_size")

@ミラー
--label:配置
--track@alpha:透明度,0,100,0
--track@decrease:減衰,0,500,0
--track@boundary:境目調整,-2000,2000,0,1
--select@direction:ミラーの方向=1,上側=0,下側=1,左側=2,右側=3
--check@center:中心の位置を変更,0
--[[pixelshader@psmain:
cbuffer constant0 : register(b0) {
	float cx,cy;
	float ax,ay;
};
float4 psmain(float4 input : SV_Position) : SV_Target {
	int2 pos = int2(input.xy);
	float a = saturate(1.0 - (pos.x - cx) * ax - (pos.y - cy) * ay);
	return float4(0,0,0,a);
}
]]
a = 1-alpha/100
baseW,baseH = obj.w,obj.h
w,h = baseW/2,baseH/2
ofs = boundary
ox,oy,tx,ty = 0,0,0,0
cx,cy,ax,ay = 0,0,0,0
if (direction == 0) then
	if (ofs < 0) then
		h = math.max(0,h + ofs/2)
		ofs = 0
	end
	oy = -(h + ofs)
	ty = -h*2 + baseH
	ix,iy = 1,-1
	ay = decrease / (baseH*100) 
elseif (direction == 1) then
	if (ofs < 0) then
		h = math.max(0,h + ofs/2)
		ofs = 0
	end
	oy = h + ofs
	ix,iy = 1,-1
	cy = baseH
	ay = -decrease / (baseH*100) 
elseif (direction == 2) then
	if (ofs < 0) then
		w = math.max(0,w + ofs/2)
		ofs = 0
	end
	ox = -(w + ofs)
	tx = -w*2 + baseW
	ix,iy = -1,1
	ax = decrease / (baseW*100)
elseif (direction == 3) then
	if (ofs < 0) then
		w = math.max(0,w + ofs/2)
		ofs = 0
	end
	ox = w + ofs
	ix,iy = -1,1
	cx = baseW
	ax = -decrease / (baseW*100) 
end
if (w < 1 or h < 1) then
	obj.load("plane",0,0)
else
	obj.setoption("drawtarget","tempbuffer",w*2+math.abs(ox)*2,h*2+math.abs(oy)*2)
	obj.drawpoly(-w-ox,-h-oy,0, w-ox,-h-oy,0, w-ox,h-oy,0, -w-ox,h-oy,0, tx,ty, tx+w*2,ty, tx+w*2,ty+h*2, tx,ty+h*2);
	-- ミラー部分
	obj.pixelshader("psmain","object",nil,{cx,cy,ax,ay},"mask");
	obj.drawpoly(-w+ox,-h+oy,0, w+ox,-h+oy,0, w+ox,h+oy,0, -w+ox,h+oy,0, tx+w-w*ix,ty+h-h*iy, tx+w+w*ix,ty+h-h*iy, tx+w+w*ix,ty+h+h*iy, tx+w-w*ix,ty+h+h*iy, a);
	obj.load("tempbuffer")
end
if (center == 0) then
	obj.cx = obj.cx - ox - tx - w + baseW/2
	obj.cy = obj.cy - oy - ty - h + baseH/2
end

@粒子化
--track@start:開始時間,-100,100,0,0.01
--track@step:再生速度,-10,10,1,0.01
--track0:起点X,-2000,2000,0
--track1:起点Y,-2000,2000,0
--track2:速度,0,100,20
--track3:角度,-360,360,0
--track@vg:粒子速度,0,10,1.0,0.01
--track@vz:拡大速度,0,10,1.0,0.01
--track@fluc:ゆらぎ,0,500,100,1
--track@dist:ゆがみ,0,500,100,1
--track@blur:ぼかし,0,100,10,1
--filter

-- 粒子化前の部分のみ描画するPixelShader
--[[pixelshader@psmain:
Texture2D tempbuffer : register(t0);
Texture2D random : register(t1);
SamplerState sampler0 : register(s0);
cbuffer constant0 : register(b0) {
	float2 center;
	float time;
	float dist;
	float blur;
};
float4 psmain(float4 input : SV_Position) : SV_Target {
	float rand = random.Sample(sampler0, input.xy / 16384.0).r;
	float now = length(float2(input.xy) - center) - time + (rand * dist) + blur;
	if (now < 0) {
		discard;
	}
	return tempbuffer[int2(input.xy)] * smoothstep(0, blur, now);
}
]]

-- 粒子化後の部分を加算合成するComputeShader
--[[computeshader@csmain:
RWTexture2D<half4> buffer : register(u0);
Texture2D tempbuffer : register(t0);
Texture2D random : register(t1);
SamplerState sampler0 : register(s0);
cbuffer constant0 : register(b0) {
	float2 center;
	float2 speed;
	float zspeed;
	float time;
	float fluc;
	float dist;
};
[numthreads(1, 1, 1)]
void csmain(uint2 pos : SV_DispatchThreadID) {
	float rand = random.SampleLevel(sampler0, float2(pos) / 16384.0, 0).r;
	float now = length(float2(pos) - center) - time + (rand * dist) ;
	if (now >= 0) {
		return;
	}
	float4 col = tempbuffer[pos];
	if (col.a <= 0) {
		return;
	}
	float2 vec = pos + (rand * fluc);
	float2 spd;
	spd.x = speed.x + sin(radians(vec.x * 2.5)) + sin(radians(vec.x * 9.0));
	spd.y = speed.y + cos(radians(vec.y * 2.8125)) + cos(radians(vec.y * 11.25));
	int2 xy = round(float2(pos) + spd * (now * now * zspeed));
	// 同時アクセスする可能性があるのであまり良くない・・
	col += buffer[xy];
	col.a = saturate(col.a);
	buffer[xy] += col;
}
]]

local cx = obj.track0
local cy = obj.track1
local v = obj.track2/5
local vx = math.sin(obj.track3*math.pi/180)*v*vg
local vy = -math.cos(obj.track3*math.pi/180)*v*vg
local time = obj.time*step
if( step < 0 ) then 
	time = time+start
else
	time = time-start
end
time = time*v*vz*20
if(vz > 0) then
	vz = 1/(vz*64)
end

if(obj.getinfo("filter")) then
	obj.clearbuffer("framebuffer")
else
	obj.effect("オフスクリーン描画")
end
obj.copybuffer("tempbuffer","object")
cx = cx + obj.w/2;
cy = cy + obj.h/2;
-- 粒子化前の部分をフレームバッファに描画する
obj.pixelshader("psmain","framebuffer",{"tempbuffer","random"},{cx,cy,time,dist,blur},"draw","loop");
-- 粒子化後の部分をオブジェクトとする
obj.clearbuffer("object")
obj.computeshader("csmain","object",{"tempbuffer","random"},{cx,cy,vx,vy,vz,time,fluc,dist},obj.w,obj.h,1,"loop");
if(blur > 0) then
	obj.effect("ぼかし","範囲",blur,"サイズ固定",1)
end
if(obj.getinfo("filter")) then
	obj.draw()
	obj.copybuffer("object","framebuffer")
end
