Vector3_Tips.lua 16 KB

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