Whitemambaa

TweenModel

Apr 23rd, 2014
371
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.31 KB | None | 0 0
  1. --By xXxMoNkEyMaNxXx
  2. --localize variables
  3. local tick=tick
  4.  
  5. local pi=math.pi
  6. local tau=2*pi
  7. local atan2=math.atan2
  8. local cos=math.cos
  9. local sin=math.sin
  10. local tan=math.tan
  11. local exp=math.exp
  12. local log=math.log
  13. local acos=math.acos
  14. local sqrt=math.sqrt
  15. local max=math.max
  16.  
  17. --CFrame a model
  18. local function MulCFrame(obj,cf)
  19.     if obj:IsA'BasePart' then
  20.         obj.CFrame=cf*obj.CFrame
  21.     end
  22.     for _,child in next,obj:GetChildren() do
  23.         MulCFrame(child,cf)
  24.     end
  25. end
  26. local function SetModelCFrame(model,CFrame)
  27.     MulCFrame(model,CFrame*model:GetModelCFrame():inverse())
  28. end
  29.  
  30. --Quaternion spherical-linear interpolation stuff
  31. local function Qinv(q)--Inverse. (q^-1)
  32.     local w,x,y,z=q[1],q[2],q[3],q[4]
  33.     local m=w*w+x*x+y*y+z*z
  34.     if m>0 then
  35.         return {w/m,-x/m,-y/m,-z/m}
  36.     else
  37.         return {0,0,0,0}
  38.     end
  39. end
  40.  
  41. local function Qmul(q1,q2)
  42.     local w1,x1,y1,z1,w2,x2,y2,z2=q1[1],q1[2],q1[3],q1[4],q2[1],q2[2],q2[3],q2[4]
  43.     return {w1*w2-x1*x2-y1*y2-z1*z2,w1*x2+x1*w2+y1*z2-z1*y2,w1*y2-x1*z2+y1*w2+z1*x2,w1*z2+x1*y2-y1*x2+z1*w2}
  44. end
  45.  
  46. local function Qpow(q,exponent,choice)
  47.     choice=choice or 0
  48.     local w,x,y,z=q[1],q[2],q[3],q[4]
  49.     local vv=x*x+y*y+z*z
  50.     if vv>0 then
  51.         --Convert to polar form and exponentiate (all in one go)
  52.         local v=sqrt(vv)
  53.         local m=(w*w+vv)^(0.5*exponent)
  54.         local theta=exponent*(atan2(v,w)+tau*choice)--swag
  55.         local s=m*sin(theta)/v
  56.         return {m*cos(theta),x*s,y*s,z*s}
  57.     else--This is a regular number.  srs.  lol.
  58.         if w<0 then--Quaternions, umad? u dun fool me nub
  59.             local m=(-w)^exponent
  60.             local s=m*sin(pi*exponent)*sqrt(3)/3
  61.             return {m*cos(pi*exponent),s,s,s}
  62.         else
  63.             return {w^exponent,0,0,0}
  64.         end
  65.     end
  66. end
  67.  
  68. local function QuaternionFromCFrame(cf)
  69.     local mx,my,mz,m00,m01,m02,m10,m11,m12,m20,m21,m22=cf:components()
  70.     local trace=m00+m11+m22
  71.     if trace>0 then
  72.         local s=sqrt(1+trace)
  73.         local recip=0.5/s
  74.         return s*0.5,(m21-m12)*recip,(m02-m20)*recip,(m10-m01)*recip
  75.     else
  76.         local big=max(m00,m11,m22)
  77.         if big==m00 then
  78.             local s=sqrt(1+m00-m11-m22)
  79.             local recip=0.5/s
  80.             return (m21-m12)*recip,0.5*s,(m10+m01)*recip,(m02+m20)*recip
  81.         elseif big==m11 then
  82.             local s=sqrt(1-m00+m11-m22)
  83.             local recip=0.5/s
  84.             return (m02-m20)*recip,(m10+m01)*recip,0.5*s,(m21+m12)*recip
  85.         elseif big==m22 then
  86.             local s=sqrt(1-m00-m11+m22)
  87.             local recip=0.5/s
  88.             return (m10-m01)*recip,(m02+m20)*recip,(m21+m12)*recip,0.5*s
  89.         end
  90.     end
  91. end
  92.  
  93. --Linear interpolation from where <model> currently is to <targetCFrame> in <period> seconds
  94. local function TweenModel(model,targetCFrame,period)
  95.     period=period or 1
  96.     local c0=model:GetModelCFrame()
  97.     local q0={QuaternionFromCFrame(c0)}
  98.     local q1={QuaternionFromCFrame(targetCFrame)}
  99.     if q0[1]*q1[1]+q0[2]*q1[2]+q0[3]*q1[3]+q0[4]*q1[4]<0 then
  100.         q1={-q1[1],-q1[2],-q1[3],-q1[4]}
  101.     end
  102.     local dq=Qmul(Qinv(q0),q1)
  103.     local t0=tick()
  104.     repeat
  105.         wait()
  106.         local t=(tick()-t0)/period
  107.         if t>1 then
  108.             break
  109.         end
  110.         local qt=Qmul(q0,Qpow(dq,t))
  111.         local pt=c0.p:lerp(targetCFrame.p,t)
  112.         SetModelCFrame(model,CFrame.new(pt.x,pt.y,pt.z,qt[2],qt[3],qt[4],qt[1]))
  113.     until t>=1
  114.     SetModelCFrame(model,targetCFrame)
  115. end
  116.  
  117. --use it like this:
  118. TweenModel(workspace.Model,CFrame.new(25*(2*math.random()-1),25*math.random(),25*(2*math.random()-1),2*math.random()-1,2*math.random()-1,2*math.random()-1,2*math.random()-1),4)--4 is how many seconds it should take
Advertisement
Add Comment
Please, Sign In to add comment