Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --By xXxMoNkEyMaNxXx
- --localize variables
- local tick=tick
- local pi=math.pi
- local tau=2*pi
- local atan2=math.atan2
- local cos=math.cos
- local sin=math.sin
- local tan=math.tan
- local exp=math.exp
- local log=math.log
- local acos=math.acos
- local sqrt=math.sqrt
- local max=math.max
- --CFrame a model
- local function MulCFrame(obj,cf)
- if obj:IsA'BasePart' then
- obj.CFrame=cf*obj.CFrame
- end
- for _,child in next,obj:GetChildren() do
- MulCFrame(child,cf)
- end
- end
- local function SetModelCFrame(model,CFrame)
- MulCFrame(model,CFrame*model:GetModelCFrame():inverse())
- end
- --Quaternion spherical-linear interpolation stuff
- local function Qinv(q)--Inverse. (q^-1)
- local w,x,y,z=q[1],q[2],q[3],q[4]
- local m=w*w+x*x+y*y+z*z
- if m>0 then
- return {w/m,-x/m,-y/m,-z/m}
- else
- return {0,0,0,0}
- end
- end
- local function Qmul(q1,q2)
- 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]
- 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}
- end
- local function Qpow(q,exponent,choice)
- choice=choice or 0
- local w,x,y,z=q[1],q[2],q[3],q[4]
- local vv=x*x+y*y+z*z
- if vv>0 then
- --Convert to polar form and exponentiate (all in one go)
- local v=sqrt(vv)
- local m=(w*w+vv)^(0.5*exponent)
- local theta=exponent*(atan2(v,w)+tau*choice)--swag
- local s=m*sin(theta)/v
- return {m*cos(theta),x*s,y*s,z*s}
- else--This is a regular number. srs. lol.
- if w<0 then--Quaternions, umad? u dun fool me nub
- local m=(-w)^exponent
- local s=m*sin(pi*exponent)*sqrt(3)/3
- return {m*cos(pi*exponent),s,s,s}
- else
- return {w^exponent,0,0,0}
- end
- end
- end
- local function QuaternionFromCFrame(cf)
- local mx,my,mz,m00,m01,m02,m10,m11,m12,m20,m21,m22=cf:components()
- local trace=m00+m11+m22
- if trace>0 then
- local s=sqrt(1+trace)
- local recip=0.5/s
- return s*0.5,(m21-m12)*recip,(m02-m20)*recip,(m10-m01)*recip
- else
- local big=max(m00,m11,m22)
- if big==m00 then
- local s=sqrt(1+m00-m11-m22)
- local recip=0.5/s
- return (m21-m12)*recip,0.5*s,(m10+m01)*recip,(m02+m20)*recip
- elseif big==m11 then
- local s=sqrt(1-m00+m11-m22)
- local recip=0.5/s
- return (m02-m20)*recip,(m10+m01)*recip,0.5*s,(m21+m12)*recip
- elseif big==m22 then
- local s=sqrt(1-m00-m11+m22)
- local recip=0.5/s
- return (m10-m01)*recip,(m02+m20)*recip,(m21+m12)*recip,0.5*s
- end
- end
- end
- --Linear interpolation from where <model> currently is to <targetCFrame> in <period> seconds
- local function TweenModel(model,targetCFrame,period)
- period=period or 1
- local c0=model:GetModelCFrame()
- local q0={QuaternionFromCFrame(c0)}
- local q1={QuaternionFromCFrame(targetCFrame)}
- if q0[1]*q1[1]+q0[2]*q1[2]+q0[3]*q1[3]+q0[4]*q1[4]<0 then
- q1={-q1[1],-q1[2],-q1[3],-q1[4]}
- end
- local dq=Qmul(Qinv(q0),q1)
- local t0=tick()
- repeat
- wait()
- local t=(tick()-t0)/period
- if t>1 then
- break
- end
- local qt=Qmul(q0,Qpow(dq,t))
- local pt=c0.p:lerp(targetCFrame.p,t)
- SetModelCFrame(model,CFrame.new(pt.x,pt.y,pt.z,qt[2],qt[3],qt[4],qt[1]))
- until t>=1
- SetModelCFrame(model,targetCFrame)
- end
- --use it like this:
- 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