123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674 |
- --------------------------------------------------------------------------------
- -- Copyright (c) 2015 , 蒙占志(topameng) topameng@gmail.com
- -- All rights reserved.
- -- Use, modification and distribution are subject to the "MIT License"
- --------------------------------------------------------------------------------
- -- added by wsh @ 2017-12-28
- -- 注意:
- -- 1、已经被修改,别从tolua轻易替换来做升级
- local math = math
- local acos = math.acos
- local sqrt = math.sqrt
- local max = math.max
- local min = math.min
- local clamp = Mathf.Clamp
- local cos = math.cos
- local sin = math.sin
- local abs = math.abs
- local sign = Mathf.Sign
- local setmetatable = setmetatable
- local rawset = rawset
- local rawget = rawget
- local type = type
- local rad2Deg = 57.295779513082
- local deg2Rad = 0.017453292519943
- ---@class Vector3
- ---@field zero Vector3
- ---@field one Vector3
- Vector3 = {}
- local this = Vector3
- local _getter = {}
- local unity_vector3 = CS.UnityEngine.Vector3
- Vector3.isValueType = true
- Vector3.__index = function(t,k)
- local var = rawget(Vector3, k)
- if var ~= nil then
- return var
- end
-
- var = rawget(_getter, k)
- if var ~= nil then
- return var(t)
- end
-
- return rawget(unity_vector3, k)
- end
- function Vector3.New(x, y, z)
- local t = {x = x or 0, y = y or 0, z = z or 0}
- setmetatable(t, Vector3)
- return t
- end
- local _new = Vector3.New
- Vector3.__call = function(t,x,y,z)
- local t = {x = x or 0, y = y or 0, z = z or 0}
- setmetatable(t, Vector3)
- return t
- end
-
- function Vector3:Set(x,y,z)
- self.x = x or 0
- self.y = y or 0
- self.z = z or 0
- end
- ---@param u_v3 UnityEngine.Vector3
- function Vector3:SetUV3(u_v3)
- self.x = u_v3.x
- self.y = u_v3.y
- self.z = u_v3.z
- end
- function Vector3.Get(v)
- return v.x, v.y, v.z
- end
- ---@return Vector3
- function Vector3:Clone()
- return setmetatable({x = self.x, y = self.y, z = self.z}, Vector3)
- end
- function Vector3.Distance(va, vb)
- return sqrt((va.x - vb.x)^2 + (va.y - vb.y)^2 + (va.z - vb.z)^2)
- end
- function Vector3.DistancePow2(va, vb)
- return (va.x - vb.x)^2 + (va.y - vb.y)^2 + (va.z - vb.z)^2
- end
- function Vector3.Dot(lhs, rhs)
- return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z
- end
- function Vector3.Lerp(from, to, t)
- t = clamp(t, 0, 1)
- return _new(from.x + (to.x - from.x) * t, from.y + (to.y - from.y) * t, from.z + (to.z - from.z) * t)
- end
- function Vector3:Magnitude()
- return sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
- end
- function Vector3.Max(lhs, rhs)
- return _new(max(lhs.x, rhs.x), max(lhs.y, rhs.y), max(lhs.z, rhs.z))
- end
- function Vector3.Min(lhs, rhs)
- return _new(min(lhs.x, rhs.x), min(lhs.y, rhs.y), min(lhs.z, rhs.z))
- end
- function Vector3.Normalize(v)
- local x,y,z = v.x, v.y, v.z
- local num = sqrt(x * x + y * y + z * z)
-
- if num > 1e-5 then
- return setmetatable({x = x / num, y = y / num, z = z / num}, Vector3)
- end
-
- return setmetatable({x = 0, y = 0, z = 0}, Vector3)
- end
- function Vector3:SetNormalize()
- local num = sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
-
- if num > 1e-5 then
- self.x = self.x / num
- self.y = self.y / num
- self.z = self.z /num
- else
- self.x = 0
- self.y = 0
- self.z = 0
- end
- return self
- end
- function Vector3:GetNormalizeXYZ()
- local num = sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
- if num > 1e-5 then
- return self.x/num,self.y/num,self.z/num
- else
- return 0,0,0
- end
- end
-
- function Vector3:SqrMagnitude()
- return self.x * self.x + self.y * self.y + self.z * self.z
- end
- local dot = Vector3.Dot
- function Vector3.Angle(from, to)
- return acos(clamp(dot(from:Normalize(), to:Normalize()), -1, 1)) * rad2Deg
- end
- function Vector3.AngleNonAlloc(v1, v2)
- local dx = v1.x - v2.x
- local dz = v1.z - v2.z
- if dx * dx + dz * dz < Mathf.Epsilon then
- return 0
- end
- local dir = 90 - math.deg(Mathf.Atan2(dz, dx))
- return dir
- end
- function Vector3.Copy(from,to)
- to.x = from.x
- to.y = from.y
- to.z = from.z
- end
- function Vector3:ClampMagnitude(maxLength)
- if self:SqrMagnitude() > (maxLength * maxLength) then
- self:SetNormalize()
- self:Mul(maxLength)
- end
-
- return self
- end
- function Vector3.OrthoNormalize(va, vb, vc)
- va:SetNormalize()
- vb:Sub(vb:Project(va))
- vb:SetNormalize()
-
- if vc == nil then
- return va, vb
- end
-
- vc:Sub(vc:Project(va))
- vc:Sub(vc:Project(vb))
- vc:SetNormalize()
- return va, vb, vc
- end
-
- function Vector3.MoveTowards(current, target, maxDistanceDelta)
- local delta = target - current
- local sqrDelta = delta:SqrMagnitude()
- local sqrDistance = maxDistanceDelta * maxDistanceDelta
-
- if sqrDelta > sqrDistance then
- local magnitude = sqrt(sqrDelta)
-
- if magnitude > 1e-6 then
- delta:Mul(maxDistanceDelta / magnitude)
- delta:Add(current)
- return delta
- else
- return current:Clone()
- end
- end
-
- return target:Clone()
- end
- function Vector3.MoveTowardsNonAlloc(current, target, maxDistanceDelta, pos)
- local sqrDelta = Vector3.DistancePow2(current, target)
- local sqrDistance = maxDistanceDelta * maxDistanceDelta
- if sqrDelta > sqrDistance then
- local magnitude = sqrt(sqrDelta)
- local t = maxDistanceDelta / magnitude
- pos.x = current.x + (target.x - current.x) * t
- pos.y = current.y + (target.y - current.y) * t
- pos.z = current.z + (target.z - current.z) * t
- else
- Vector3.Copy(target,pos)
- end
- end
- function ClampedMove(lhs, rhs, clampedDelta)
- local delta = rhs - lhs
-
- if delta > 0 then
- return lhs + min(delta, clampedDelta)
- else
- return lhs - min(-delta, clampedDelta)
- end
- end
- local overSqrt2 = 0.7071067811865475244008443621048490
- local function OrthoNormalVector(vec)
- local res = _new()
-
- if abs(vec.z) > overSqrt2 then
- local a = vec.y * vec.y + vec.z * vec.z
- local k = 1 / sqrt (a)
- res.x = 0
- res.y = -vec.z * k
- res.z = vec.y * k
- else
- local a = vec.x * vec.x + vec.y * vec.y
- local k = 1 / sqrt (a)
- res.x = -vec.y * k
- res.y = vec.x * k
- res.z = 0
- end
-
- return res
- end
- function Vector3.RotateTowards(current, target, maxRadiansDelta, maxMagnitudeDelta)
- local len1 = current:Magnitude()
- local len2 = target:Magnitude()
-
- if len1 > 1e-6 and len2 > 1e-6 then
- local from = current / len1
- local to = target / len2
- local cosom = dot(from, to)
-
- if cosom > 1 - 1e-6 then
- return Vector3.MoveTowards (current, target, maxMagnitudeDelta)
- elseif cosom < -1 + 1e-6 then
- local axis = OrthoNormalVector(from)
- local q = Quaternion.AngleAxis(maxRadiansDelta * rad2Deg, axis)
- local rotated = q:MulVec3(from)
- local delta = ClampedMove(len1, len2, maxMagnitudeDelta)
- rotated:Mul(delta)
- return rotated
- else
- local angle = acos(cosom)
- local axis = Vector3.Cross(from, to)
- axis:SetNormalize ()
- local q = Quaternion.AngleAxis(min(maxRadiansDelta, angle) * rad2Deg, axis)
- local rotated = q:MulVec3(from)
- local delta = ClampedMove(len1, len2, maxMagnitudeDelta)
- rotated:Mul(delta)
- return rotated
- end
- end
-
- return Vector3.MoveTowards(current, target, maxMagnitudeDelta)
- end
- ---@return Vector3
- ---@param position Vector3
- ---@param center Vector3
- ---@param axis Vector3
- function Vector3.RotateRound(position, center, axis, angle)
- return Quaternion.AngleAxis(angle, axis) * (position - center) + center;
- end
- function Vector3:RotateRoundNonAlloc(position, center, axis, angle)
- self:CopyFromSub(position,center)
- return self:CopyFromAdd(Quaternion.AngleAxis(angle, axis) * self, center);
- end
-
- function Vector3.SmoothDamp(current, target, currentVelocity, smoothTime)
- local maxSpeed = Mathf.Infinity
- local deltaTime = Time.deltaTime
- smoothTime = max(0.0001, smoothTime)
- local num = 2 / smoothTime
- local num2 = num * deltaTime
- local num3 = 1 / (1 + num2 + 0.48 * num2 * num2 + 0.235 * num2 * num2 * num2)
- local vector2 = target:Clone()
- local maxLength = maxSpeed * smoothTime
- local vector = current - target
- vector:ClampMagnitude(maxLength)
- target = current - vector
- local vec3 = (currentVelocity + (vector * num)) * deltaTime
- currentVelocity = (currentVelocity - (vec3 * num)) * num3
- local vector4 = target + (vector + vec3) * num3
-
- if Vector3.Dot(vector2 - current, vector4 - vector2) > 0 then
- vector4 = vector2
- currentVelocity:Set(0,0,0)
- end
-
- return vector4, currentVelocity
- end
-
- function Vector3.Scale(a, b)
- local x = a.x * b.x
- local y = a.y * b.y
- local z = a.z * b.z
- return _new(x, y, z)
- end
-
- function Vector3.Cross(lhs, rhs)
- local x = lhs.y * rhs.z - lhs.z * rhs.y
- local y = lhs.z * rhs.x - lhs.x * rhs.z
- local z = lhs.x * rhs.y - lhs.y * rhs.x
- return _new(x,y,z)
- end
- ---@param target Vector3
- function Vector3:CrossNonAlloc(lhs, rhs)
- local x = lhs.y * rhs.z - lhs.z * rhs.y
- local y = lhs.z * rhs.x - lhs.x * rhs.z
- local z = lhs.x * rhs.y - lhs.y * rhs.x
- self:Set(x,y,z)
- end
-
- function Vector3:Equals(other)
- return self.x == other.x and self.y == other.y and self.z == other.z
- end
-
- function Vector3.Reflect(inDirection, inNormal)
- local num = -2 * dot(inNormal, inDirection)
- inNormal = inNormal * num
- inNormal:Add(inDirection)
- return inNormal
- end
-
- function Vector3.Project(vector, onNormal)
- local num = onNormal:SqrMagnitude()
-
- if num < 1.175494e-38 then
- return _new(0,0,0)
- end
-
- local num2 = dot(vector, onNormal)
- local v3 = onNormal:Clone()
- v3:Mul(num2/num)
- return v3
- end
-
- function Vector3.ProjectOnPlane(vector, planeNormal)
- local v3 = Vector3.Project(vector, planeNormal)
- v3:Mul(-1)
- v3:Add(vector)
- return v3
- end
- function Vector3.Slerp(from, to, t)
- local omega, sinom, scale0, scale1
- if t <= 0 then
- return from:Clone()
- elseif t >= 1 then
- return to:Clone()
- end
-
- local v2 = to:Clone()
- local v1 = from:Clone()
- local len2 = to:Magnitude()
- local len1 = from:Magnitude()
- v2:Div(len2)
- v1:Div(len1)
- local len = (len2 - len1) * t + len1
- local cosom = v1.x * v2.x + v1.y * v2.y + v1.z * v2.z
-
- if cosom > 1 - 1e-6 then
- scale0 = 1 - t
- scale1 = t
- elseif cosom < -1 + 1e-6 then
- local axis = OrthoNormalVector(from)
- local q = Quaternion.AngleAxis(180.0 * t, axis)
- local v = q:MulVec3(from)
- v:Mul(len)
- return v
- else
- omega = acos(cosom)
- sinom = sin(omega)
- scale0 = sin((1 - t) * omega) / sinom
- scale1 = sin(t * omega) / sinom
- end
- v1:Mul(scale0)
- v2:Mul(scale1)
- v2:Add(v1)
- v2:Mul(len)
- return v2
- end
- function Vector3:Mul(q)
- if type(q) == "number" then
- self.x = self.x * q
- self.y = self.y * q
- self.z = self.z * q
- else
- self:MulQuat(q)
- end
-
- return self
- end
- function Vector3:Div(d)
- self.x = self.x / d
- self.y = self.y / d
- self.z = self.z / d
-
- return self
- end
- function Vector3:Add(vb)
- self.x = self.x + vb.x
- self.y = self.y + vb.y
- self.z = self.z + vb.z
-
- return self
- end
- function Vector3:AddXYZ(x,y,z)
- self.x = self.x + x
- self.y = self.y + y
- self.z = self.z + z
- return self
- end
- function Vector3:Sub(vb)
- self.x = self.x - vb.x
- self.y = self.y - vb.y
- self.z = self.z - vb.z
-
- return self
- end
- function Vector3.NewFrom(t)
- local x = t and t.x or 0
- local y = t and t.y or 0
- local z = t and t.z or 0
- local vec = {x = x or 0, y = y or 0, z = z or 0}
- setmetatable(vec, Vector3)
- return vec
- end
- function Vector3.AngleBetween(v1, v2)
- local dx = v1.x - v2.x
- local dz = v1.z - v2.z
- if dx * dx + dz * dz < Mathf.Epsilon then
- return 0
- end
- local dir = 90 - math.deg(Mathf.Atan2(dz, dx))
- return dir
- end
- function Vector3.LerpWithFrom(from, to, t)
- t = clamp(t, 0, 1)
- from.x = from.x + (to.x - from.x) * t
- from.y = from.y + (to.y - from.y) * t
- from.z = from.z + (to.z - from.z) * t
- return from
- end
- function Vector3:MulQuat(quat)
- local num = quat.x * 2
- local num2 = quat.y * 2
- local num3 = quat.z * 2
- local num4 = quat.x * num
- local num5 = quat.y * num2
- local num6 = quat.z * num3
- local num7 = quat.x * num2
- local num8 = quat.x * num3
- local num9 = quat.y * num3
- local num10 = quat.w * num
- local num11 = quat.w * num2
- local num12 = quat.w * num3
-
- local x = (((1 - (num5 + num6)) * self.x) + ((num7 - num12) * self.y)) + ((num8 + num11) * self.z)
- local y = (((num7 + num12) * self.x) + ((1 - (num4 + num6)) * self.y)) + ((num9 - num10) * self.z)
- local z = (((num8 - num11) * self.x) + ((num9 + num10) * self.y)) + ((1 - (num4 + num5)) * self.z)
-
- self:Set(x, y, z)
- return self
- end
- function Vector3.AngleAroundAxis (from, to, axis)
- from = from - Vector3.Project(from, axis)
- to = to - Vector3.Project(to, axis)
- local angle = Vector3.Angle (from, to)
- return angle * (Vector3.Dot (axis, Vector3.Cross (from, to)) < 0 and -1 or 1)
- end
- function Vector3.DistancePow2(va, vb)
- return (va.x - vb.x)^2 + (va.y - vb.y)^2 + (va.z - vb.z)^2
- end
- function Vector3:CopyFrom(target)
- if target and self ~= target then
- self:Set(target.x,target.y,target.z)
- end
- end
- function Vector3:CopyFromAdd(va, vb)
- self.x = va.x + vb.x
- self.y = va.y + vb.y
- self.z = va.z + vb.z
- return self
- end
- function Vector3:CopyFromSub(va, vb)
- self.x = va.x - vb.x
- self.y = va.y - vb.y
- self.z = va.z - vb.z
- return self
- end
- ---@param forward Vector3
- ---@param right Vector3
- ---@param v Vector3
- function Vector3.MoveLocalAxisXZ(forward,right,v)
- local fN = Vector3.Normalize(forward)
- local rN = Vector3.Normalize(right)
- local vec = fN*v.z+rN*v.x
- return vec
- end
- ---@param forward Vector3
- ---@param right Vector3
- ---@param v Vector3
- function Vector3:MoveLocalAxisXZNonAlloc(forward,right,v)
- local fN_x,fN_y,fN_z = forward:GetNormalizeXYZ()
- local rN_x,rN_y,rN_z = right:GetNormalizeXYZ()
- self:Set(fN_x*v.z+rN_x*v.x,fN_y*v.z+rN_y*v.x,fN_z*v.z+rN_z*v.x)
- end
- function Vector3.MoveTowardsNonAlloc(current, target, maxDistanceDelta, pos)
- local sqrDelta = Vector3.DistancePow2(current, target)
- local sqrDistance = maxDistanceDelta * maxDistanceDelta
- if sqrDelta > sqrDistance then
- local magnitude = sqrt(sqrDelta)
- local t = maxDistanceDelta / magnitude
- pos.x = current.x + (target.x - current.x) * t
- pos.y = current.y + (target.y - current.y) * t
- pos.z = current.z + (target.z - current.z) * t
- else
- pos:CopyFrom(target)
- end
- end
- Vector3.__tostring = function(self)
- return "["..self.x..","..self.y..","..self.z.."]"
- end
- Vector3.__div = function(va, d)
- return _new(va.x / d, va.y / d, va.z / d)
- end
- Vector3.__mul = function(va, d)
- if type(d) == "number" then
- return _new(va.x * d, va.y * d, va.z * d)
- else
- local vec = va:Clone()
- vec:MulQuat(d)
- return vec
- end
- end
- Vector3.__add = function(va, vb)
- return _new(va.x + vb.x, va.y + vb.y, va.z + vb.z)
- end
- Vector3.__sub = function(va, vb)
- return _new(va.x - vb.x, va.y - vb.y, va.z - vb.z)
- end
- Vector3.__unm = function(va)
- return _new(-va.x, -va.y, -va.z)
- end
- Vector3.__eq = function(a,b)
- if not a.x or not b.x then
- return false
- end
- if not this.eqTemp then
- this.eqTemp = Vector3.zero
- end
- this.eqTemp.x = a.x - b.x
- this.eqTemp.y = a.y - b.y
- this.eqTemp.z = a.z - b.z
- local delta = this.eqTemp:SqrMagnitude()
- return delta < 1e-10
- end
- ---@param vec Vector3
- function Vector3.IsZero(vec)
- return vec.x ==0 and vec.y == 0 and vec.z == 0
- end
- ---@param vec Vector4
- function Vector3:IsSelfMetatable(vec)
- return self.x == nil
- end
- _getter.up = function() return _new(0,1,0) end
- _getter.down = function() return _new(0,-1,0) end
- _getter.right = function() return _new(1,0,0) end
- _getter.left = function() return _new(-1,0,0) end
- _getter.forward = function() return _new(0,0,1) end
- _getter.back = function() return _new(0,0,-1) end
- _getter.zero = function() return _new(0,0,0) end
- _getter.one = function() return _new(1,1,1) end
- _getter.magnitude = Vector3.Magnitude
- _getter.normalized = Vector3.Normalize
- _getter.sqrMagnitude= Vector3.SqrMagnitude
- ---@type UnityEngine.Vector3
- Vector3.unity_vector3 = CS.UnityEngine.Vector3
- CS.UnityEngine.Vector3 = Vector3
- setmetatable(Vector3, Vector3)
- Vector3.upNonAlloc = Vector3(0,1,0)
- Vector3.downNonAlloc = Vector3(0,-1,0)
- Vector3.rightNonAlloc = Vector3(1,0,0)
- Vector3.leftNonAlloc = Vector3(-1,0,0)
- Vector3.forwardNonAlloc = Vector3(0,0,1)
- Vector3.backNonAlloc = Vector3(0,0,-1)
- Vector3.zeroNonAlloc = Vector3(0,0,0)
- Vector3.oneNonAlloc = Vector3(1,1,1)
|