Advertisement
MiaMyLove

SunShineSilver.mdA Vector3 for Lua

Apr 10th, 2019
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.47 KB | None | 0 0
  1. local acos  = math.acos
  2. local sqrt  = math.sqrt
  3. local max   = math.max
  4. local min   = math.min
  5. local clamp = math.clamp
  6. local cos   = math.cos
  7. local sin   = math.sin
  8. local abs   = math.abs
  9. local sign  = math.sign
  10. local setmetatable = setmetatable
  11. local rawset = rawset
  12. local rawget = rawget
  13.  
  14. local rad2Deg = math.rad2Deg
  15. local deg2Rad = math.deg2Rad
  16.  
  17. Vector3 =
  18. {  
  19.     class = "Vector3",
  20. }
  21.  
  22. local fields = {}
  23.  
  24. setmetatable(Vector3, Vector3)
  25.  
  26. Vector3.__index = function(t,k)
  27.     local var = rawget(Vector3, k)
  28.    
  29.     if var == nil then                         
  30.         var = rawget(fields, k)
  31.        
  32.         if var ~= nil then
  33.             return var(t)              
  34.         end    
  35.     end
  36.    
  37.     return var
  38. end
  39.  
  40. Vector3.__call = function(t,x,y,z)
  41.     return Vector3.New(x,y,z)
  42. end
  43.  
  44. function Vector3.New(x, y, z)
  45.     local v = {x = x or 0, y = y or 0, z = z or 0}     
  46.     setmetatable(v, Vector3)       
  47.     return v
  48. end
  49.    
  50. function Vector3:Set(x,y,z)
  51.     self.x = x or 0
  52.     self.y = y or 0
  53.     self.z = z or 0
  54. end
  55.  
  56. function Vector3:Get() 
  57.     return self.x, self.y, self.z  
  58. end
  59.  
  60. function Vector3:Clone()
  61.     return Vector3.New(self.x, self.y, self.z)
  62. end
  63.  
  64. function Vector3.Distance(va, vb)
  65.     return sqrt((va.x - vb.x)^2 + (va.y - vb.y)^2 + (va.z - vb.z)^2)
  66. end
  67.  
  68. function Vector3.Dot(lhs, rhs)
  69.     return (((lhs.x * rhs.x) + (lhs.y * rhs.y)) + (lhs.z * rhs.z))
  70. end
  71.  
  72. function Vector3.Lerp(from, to, t) 
  73.     t = clamp(t, 0, 1)
  74.     return Vector3.New(from.x + ((to.x - from.x) * t), from.y + ((to.y - from.y) * t), from.z + ((to.z - from.z) * t))
  75. end
  76.  
  77. function Vector3:Magnitude()
  78.     return sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
  79. end
  80.  
  81. function Vector3.Max(lhs, rhs)
  82.     return Vector3.New(max(lhs.x, rhs.x), max(lhs.y, rhs.y), max(lhs.z, rhs.z))
  83. end
  84.  
  85. function Vector3.Min(lhs, rhs)
  86.     return Vector3.New(min(lhs.x, rhs.x), min(lhs.y, rhs.y), min(lhs.z, rhs.z))
  87. end
  88.  
  89. function Vector3:Normalize()
  90.     local v = self:Clone()
  91.     return v:SetNormalize()
  92. end
  93.  
  94. function Vector3:SetNormalize()
  95.     local num = self:Magnitude()   
  96.    
  97.     if num == 1 then
  98.         return self
  99.     elseif num > 1e-5 then    
  100.         self:Div(num)
  101.     else    
  102.         self:Set(0,0,0)
  103.     end
  104.  
  105.     return self
  106. end
  107.    
  108. function Vector3:SqrMagnitude()
  109.     return self.x * self.x + self.y * self.y + self.z * self.z
  110. end
  111.  
  112. local dot = Vector3.Dot
  113.  
  114. function Vector3.Angle(from, to)
  115.     return acos(clamp(dot(from:Normalize(), to:Normalize()), -1, 1)) * rad2Deg
  116. end
  117.  
  118. function Vector3:ClampMagnitude(maxLength) 
  119.     if self:SqrMagnitude() > (maxLength * maxLength) then    
  120.         self:SetNormalize()
  121.         self:Mul(maxLength)        
  122.     end
  123.    
  124.     return self
  125. end
  126.  
  127.  
  128. function Vector3.OrthoNormalize(va, vb, vc)
  129.     va:SetNormalize()
  130.     vb:Sub(vb:Project(va))
  131.     vb:SetNormalize()
  132.    
  133.     if vc == nil then
  134.         return va, vb
  135.     end
  136.    
  137.     vc:Sub(vc:Project(va))
  138.     vc:Sub(vc:Project(vb))
  139.     vc:SetNormalize()      
  140.     return va, vb, vc
  141. end
  142.  
  143. function Vector3.RotateTowards2(from, to, maxRadiansDelta, maxMagnitudeDelta)  
  144.     local v2    = to:Clone()
  145.     local v1    = from:Clone()
  146.     local len2  = to:Magnitude()
  147.     local len1  = from:Magnitude() 
  148.     v2:Div(len2)
  149.     v1:Div(len1)
  150.    
  151.     local dota  = dot(v1, v2)
  152.     local angle = acos(dota)           
  153.     local theta = min(angle, maxRadiansDelta)  
  154.     local len   = 0
  155.    
  156.     if len1 < len2 then
  157.         len = min(len2, len1 + maxMagnitudeDelta)
  158.     elseif len1 == len2 then
  159.         len = len1
  160.     else
  161.         len = max(len2, len1 - maxMagnitudeDelta)
  162.     end
  163.                            
  164.     v2:Sub(v1 * dota)
  165.     v2:SetNormalize()    
  166.     v2:Mul(sin(theta))
  167.     v1:Mul(cos(theta))
  168.     v2:Add(v1)
  169.     v2:SetNormalize()
  170.     v2:Mul(len)
  171.     return v2  
  172. end
  173.  
  174. function Vector3.RotateTowards1(from, to, maxRadiansDelta, maxMagnitudeDelta)  
  175.     local omega, sinom, scale0, scale1, len, theta
  176.     local v2    = to:Clone()
  177.     local v1    = from:Clone()
  178.     local len2  = to:Magnitude()
  179.     local len1  = from:Magnitude() 
  180.     v2:Div(len2)
  181.     v1:Div(len1)
  182.    
  183.     local cosom = dot(v1, v2)
  184.    
  185.     if len1 < len2 then
  186.         len = min(len2, len1 + maxMagnitudeDelta)  
  187.     elseif len1 == len2 then
  188.         len = len1
  189.     else
  190.         len = max(len2, len1 - maxMagnitudeDelta)
  191.     end    
  192.    
  193.     if 1 - cosom > 1e-6 then   
  194.         omega   = acos(cosom)
  195.         theta   = min(omega, maxRadiansDelta)      
  196.         sinom   = sin(omega)
  197.         scale0  = sin(omega - theta) / sinom
  198.         scale1  = sin(theta) / sinom
  199.        
  200.         v1:Mul(scale0)
  201.         v2:Mul(scale1)
  202.         v2:Add(v1)
  203.         v2:Mul(len)
  204.         return v2
  205.     else       
  206.         v1:Mul(len)
  207.         return v1
  208.     end        
  209. end
  210.    
  211. function Vector3.MoveTowards(current, target, maxDistanceDelta)
  212.     local delta = target - current 
  213.     local sqrDelta = delta:SqrMagnitude()
  214.     local sqrDistance = maxDistanceDelta * maxDistanceDelta
  215.    
  216.     if sqrDelta > sqrDistance then    
  217.         local magnitude = sqrt(sqrDelta)
  218.        
  219.         if magnitude > 1e-6 then
  220.             delta:Mul(maxDistanceDelta / magnitude)
  221.             delta:Add(current)
  222.             return delta
  223.         else
  224.             return current:Clone()
  225.         end
  226.     end
  227.    
  228.     return target:Clone()
  229. end
  230.  
  231. function ClampedMove(lhs, rhs, clampedDelta)
  232.     local delta = rhs - lhs
  233.    
  234.     if delta > 0 then
  235.         return lhs + min(delta, clampedDelta)
  236.     else
  237.         return lhs - min(-delta, clampedDelta)
  238.     end
  239. end
  240.  
  241. local overSqrt2 = 0.7071067811865475244008443621048490
  242.  
  243. local function OrthoNormalVector(vec)
  244.     local res = Vector3.New()
  245.    
  246.     if abs(vec.z) > overSqrt2 then         
  247.         local a = vec.y * vec.y + vec.z * vec.z
  248.         local k = 1 / sqrt (a)
  249.         res.x = 0
  250.         res.y = -vec.z * k
  251.         res.z = vec.y * k
  252.     else           
  253.         local a = vec.x * vec.x + vec.y * vec.y
  254.         local k = 1 / sqrt (a)
  255.         res.x = -vec.y * k
  256.         res.y = vec.x * k
  257.         res.z = 0
  258.     end
  259.    
  260.     return res
  261. end
  262.  
  263. function Vector3.RotateTowards(current, target, maxRadiansDelta, maxMagnitudeDelta)
  264.     local len1 = current:Magnitude()
  265.     local len2 = target:Magnitude()
  266.    
  267.     if len1 > 1e-6 and len2 > 1e-6 then
  268.         local from = current / len1
  269.         local to = target / len2       
  270.         local cosom = dot(from, to)
  271.                
  272.         if cosom > 1 - 1e-6 then       
  273.             return Vector3.MoveTowards (current, target, maxMagnitudeDelta)    
  274.         elseif cosom < -1 + 1e-6 then      
  275.             local axis = OrthoNormalVector(from)                       
  276.             local q = Quaternion.AngleAxis(maxRadiansDelta * rad2Deg, axis)
  277.             local rotated = q:MulVec3(from)
  278.             local delta = ClampedMove(len1, len2, maxMagnitudeDelta)
  279.             rotated:Mul(delta)
  280.             return rotated
  281.         else       
  282.             local angle = acos(cosom)
  283.             local axis = Vector3.Cross(from, to)
  284.             axis:SetNormalize ()
  285.             local q = Quaternion.AngleAxis(min(maxRadiansDelta, angle) * rad2Deg, axis)        
  286.             local rotated = q:MulVec3(from)
  287.             local delta = ClampedMove(len1, len2, maxMagnitudeDelta)
  288.             rotated:Mul(delta)
  289.             return rotated
  290.         end
  291.     end
  292.        
  293.     return Vector3.MoveTowards(current, target, maxMagnitudeDelta)
  294. end
  295.    
  296. function Vector3.SmoothDamp(current, target, currentVelocity, smoothTime)
  297.     local maxSpeed = math.huge
  298.     local deltaTime = Time.deltaTime
  299.     smoothTime = max(0.0001, smoothTime)
  300.     local num = 2 / smoothTime
  301.     local num2 = num * deltaTime
  302.     local num3 = 1 / (((1 + num2) + ((0.48 * num2) * num2)) + (((0.235 * num2) * num2) * num2))    
  303.     local vector2 = target:Clone()
  304.     local maxLength = maxSpeed * smoothTime
  305.     local vector = current - target
  306.     vector:ClampMagnitude(maxLength)
  307.     target = current - vector
  308.     local vec3 = (currentVelocity + (vector * num)) * deltaTime
  309.     currentVelocity = (currentVelocity - (vec3 * num)) * num3
  310.     local vector4 = target + (vector + vec3) * num3
  311.    
  312.     if Vector3.Dot(vector2 - current, vector4 - vector2) > 0 then    
  313.         vector4 = vector2
  314.         currentVelocity:Set(0,0,0)
  315.     end
  316.    
  317.     return vector4, currentVelocity
  318. end
  319.    
  320. function Vector3.Scale(a, b)
  321.     local v = a:Clone()
  322.     return v:SetScale(b)
  323. end
  324.  
  325. function Vector3:SetScale(b)
  326.     self.x = self.x * b.x
  327.     self.y = self.y * b.y
  328.     self.z = self.z * b.z  
  329.     return self
  330. end
  331.    
  332. function Vector3.Cross(lhs, rhs)
  333.     local x = lhs.y * rhs.z - lhs.z * rhs.y
  334.     local y = lhs.z * rhs.x - lhs.x * rhs.z
  335.     local z = lhs.x * rhs.y - lhs.y * rhs.x
  336.     return Vector3.New(x,y,z)  
  337. end
  338.    
  339. function Vector3:Equals(other)
  340.     return self.x == other.x and self.y == other.y and self.z == other.z
  341. end
  342.        
  343. function Vector3.Reflect(inDirection, inNormal)
  344.     local num = -2 * dot(inNormal, inDirection)
  345.     inNormal = inNormal * num
  346.     inNormal:Add(inDirection)
  347.     return inNormal
  348. end
  349.  
  350.    
  351. function Vector3.Project(vector, onNormal)
  352.     local num = onNormal:SqrMagnitude()
  353.    
  354.     if num < 1.175494e-38 then 
  355.         return Vector3.New(0,0,0)
  356.     end
  357.    
  358.     local num2 = dot(vector, onNormal)
  359.     local v3 = onNormal:Clone()
  360.     v3:Mul(num2/num)   
  361.     return v3
  362. end
  363.    
  364. function Vector3.ProjectOnPlane(vector, planeNormal)
  365.     local v3 = Vector3.Project(vector, planeNormal)
  366.     v3:Mul(-1)
  367.     v3:Add(vector)
  368.     return v3
  369. end    
  370.  
  371. function Vector3.Slerp2(from, to, t)       
  372.     if t <= 0 then
  373.         return from:Clone()
  374.     elseif t >= 1 then
  375.         return to:Clone()
  376.     end
  377.    
  378.     local v2    = to:Clone()
  379.     local v1    = from:Clone()
  380.     local len2  = to:Magnitude()
  381.     local len1  = from:Magnitude() 
  382.     v2:Div(len2)
  383.     v1:Div(len1)
  384.    
  385.     local omega = dot(v1, v2)  
  386.     local len   = (len2 - len1) * t + len1         
  387.     local theta = acos(omega) * t
  388.    
  389.     v2:Sub(v1 * omega)
  390.     v2:SetNormalize()    
  391.     v2:Mul(sin(theta))
  392.     v1:Mul(cos(theta))
  393.     v2:Add(v1)
  394.     v2:SetNormalize()
  395.     v2:Mul(len)
  396.     return v2  
  397. end
  398.  
  399. function Vector3.Slerp(from, to, t)
  400.     local omega, sinom, scale0, scale1
  401.  
  402.     if t <= 0 then     
  403.         return from:Clone()
  404.     elseif t >= 1 then     
  405.         return to:Clone()
  406.     end
  407.    
  408.     local v2    = to:Clone()
  409.     local v1    = from:Clone()
  410.     local len2  = to:Magnitude()
  411.     local len1  = from:Magnitude() 
  412.     v2:Div(len2)
  413.     v1:Div(len1)
  414.  
  415.     local len   = (len2 - len1) * t + len1
  416.     local cosom = dot(v1, v2)
  417.    
  418.     if 1 - cosom > 1e-6 then
  419.         omega   = acos(cosom)
  420.         sinom   = sin(omega)
  421.         scale0  = sin((1 - t) * omega) / sinom
  422.         scale1  = sin(t * omega) / sinom
  423.     else
  424.         scale0 = 1 - t
  425.         scale1 = t
  426.     end
  427.  
  428.     v1:Mul(scale0)
  429.     v2:Mul(scale1)
  430.     v2:Add(v1)
  431.     v2:Mul(len)
  432.     return v2
  433. end
  434.  
  435.  
  436. function Vector3:Mul(q)
  437.     if type(q) == "number" then
  438.         self.x = self.x * q
  439.         self.y = self.y * q
  440.         self.z = self.z * q
  441.     else
  442.         self:MulQuat(q)
  443.     end
  444.    
  445.     return self
  446. end
  447.  
  448. function Vector3:Div(d)
  449.     self.x = self.x / d
  450.     self.y = self.y / d
  451.     self.z = self.z / d
  452.    
  453.     return self
  454. end
  455.  
  456. function Vector3:Add(vb)
  457.     self.x = self.x + vb.x
  458.     self.y = self.y + vb.y
  459.     self.z = self.z + vb.z
  460.    
  461.     return self
  462. end
  463.  
  464. function Vector3:Sub(vb)
  465.     self.x = self.x - vb.x
  466.     self.y = self.y - vb.y
  467.     self.z = self.z - vb.z
  468.    
  469.     return self
  470. end
  471.  
  472. function Vector3:MulQuat(quat)     
  473.     local num   = quat.x * 2
  474.     local num2  = quat.y * 2
  475.     local num3  = quat.z * 2
  476.     local num4  = quat.x * num
  477.     local num5  = quat.y * num2
  478.     local num6  = quat.z * num3
  479.     local num7  = quat.x * num2
  480.     local num8  = quat.x * num3
  481.     local num9  = quat.y * num3
  482.     local num10 = quat.w * num
  483.     local num11 = quat.w * num2
  484.     local num12 = quat.w * num3
  485.    
  486.     local x = (((1 - (num5 + num6)) * self.x) + ((num7 - num12) * self.y)) + ((num8 + num11) * self.z)
  487.     local y = (((num7 + num12) * self.x) + ((1 - (num4 + num6)) * self.y)) + ((num9 - num10) * self.z)
  488.     local z = (((num8 - num11) * self.x) + ((num9 + num10) * self.y)) + ((1 - (num4 + num5)) * self.z)
  489.    
  490.     self:Set(x, y, z)  
  491.     return self
  492. end
  493.  
  494. function Vector3.AngleAroundAxis (from, to, axis)        
  495.     from = from - Vector3.Project(from, axis)
  496.     to = to - Vector3.Project(to, axis)        
  497.     local angle = Vector3.Angle (from, to)         
  498.     return angle * (Vector3.Dot (axis, Vector3.Cross (from, to)) < 0 and -1 or 1)
  499. end
  500.  
  501.  
  502. Vector3.__tostring = function(self)
  503.     return "["..self.x..","..self.y..","..self.z.."]"
  504. end
  505.  
  506. Vector3.__div = function(va, d)
  507.     return Vector3.New(va.x / d, va.y / d, va.z / d)
  508. end
  509.  
  510. Vector3.__mul = function(va, d)
  511.     if type(d) == "number" then
  512.         return Vector3.New(va.x * d, va.y * d, va.z * d)
  513.     else
  514.         local vec = va:Clone()
  515.         vec:MulQuat(d)
  516.         return vec
  517.     end
  518. end
  519.  
  520. Vector3.__add = function(va, vb)
  521.     return Vector3.New(va.x + vb.x, va.y + vb.y, va.z + vb.z)
  522. end
  523.  
  524. Vector3.__sub = function(va, vb)
  525.     return Vector3.New(va.x - vb.x, va.y - vb.y, va.z - vb.z)
  526. end
  527.  
  528. Vector3.__unm = function(va)
  529.     return Vector3.New(-va.x, -va.y, -va.z)
  530. end
  531.  
  532. Vector3.__eq = function(a,b)
  533.     local v = a - b
  534.     local delta = v:SqrMagnitude()
  535.     return delta < 1e-10
  536. end
  537.  
  538. fields.up       = function() return Vector3.New(0,1,0) end
  539. fields.down     = function() return Vector3.New(0,-1,0) end
  540. fields.right    = function() return Vector3.New(1,0,0) end
  541. fields.left     = function() return Vector3.New(-1,0,0) end
  542. fields.forward  = function() return Vector3.New(0,0,1) end
  543. fields.back     = function() return Vector3.New(0,0,-1) end
  544. fields.zero     = function() return Vector3.New(0,0,0) end
  545. fields.one      = function() return Vector3.New(1,1,1) end
  546. fields.magnitude    = Vector3.Magnitude
  547. fields.normalized   = Vector3.Normalize
  548. fields.sqrMagnitude = Vector3.SqrMagnitude
  549. print('Lua Vector3 loaded..')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement