util.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { Vec3, Mat4, Mat3 } from 'mol-math/linear-algebra'
  7. export function normalizeVec3Array<T extends Helpers.NumberArray> (a: T) {
  8. const n = a.length
  9. for (let i = 0; i < n; i += 3) {
  10. const x = a[ i ]
  11. const y = a[ i + 1 ]
  12. const z = a[ i + 2 ]
  13. const s = 1 / Math.sqrt(x * x + y * y + z * z)
  14. a[ i ] = x * s
  15. a[ i + 1 ] = y * s
  16. a[ i + 2 ] = z * s
  17. }
  18. }
  19. export function getNormalMatrix(out: Mat3, t: Mat4) {
  20. Mat3.fromMat4(out, t)
  21. Mat3.invert(out, out)
  22. Mat3.transpose(out, out)
  23. return out
  24. }
  25. const tmpV3 = Vec3.zero()
  26. export function transformPositionArray (t: Mat4, array: Helpers.NumberArray, offset: number, count: number) {
  27. for (let i = 0, il = count * 3; i < il; i += 3) {
  28. Vec3.fromArray(tmpV3, array, offset + i)
  29. Vec3.transformMat4(tmpV3, tmpV3, t)
  30. Vec3.toArray(tmpV3, array, offset + i)
  31. }
  32. }
  33. export function transformDirectionArray (n: Mat3, array: Helpers.NumberArray, offset: number, count: number) {
  34. for (let i = 0, il = count * 3; i < il; i += 3) {
  35. Vec3.fromArray(tmpV3, array, offset + i)
  36. Vec3.transformMat3(tmpV3, tmpV3, n)
  37. Vec3.toArray(tmpV3, array, offset + i)
  38. }
  39. }
  40. export function setArrayZero(array: Helpers.NumberArray) {
  41. const n = array.length
  42. for (let i = 0; i < n; ++i) array[i] = 0
  43. }
  44. /** iterate over the entire buffer and apply the radius to each vertex */
  45. export function appplyRadius(vertices: Helpers.NumberArray, radius: number) {
  46. const v = Vec3.zero()
  47. const n = vertices.length
  48. for (let i = 0; i < n; i += 3) {
  49. Vec3.fromArray(v, vertices, i)
  50. Vec3.normalize(v, v)
  51. Vec3.scale(v, v, radius)
  52. Vec3.toArray(v, vertices, i)
  53. }
  54. }
  55. /**
  56. * indexed vertex normals weighted by triangle areas http://www.iquilezles.org/www/articles/normals/normals.htm
  57. * normal array must contain only zeros
  58. */
  59. export function computeIndexedVertexNormals<T extends Helpers.NumberArray> (vertices: Helpers.NumberArray, indices: Helpers.NumberArray, normals: T) {
  60. const a = Vec3.zero()
  61. const b = Vec3.zero()
  62. const c = Vec3.zero()
  63. const cb = Vec3.zero()
  64. const ab = Vec3.zero()
  65. for (let i = 0, il = indices.length; i < il; i += 3) {
  66. const ai = indices[ i ] * 3
  67. const bi = indices[ i + 1 ] * 3
  68. const ci = indices[ i + 2 ] * 3
  69. Vec3.fromArray(a, vertices, ai)
  70. Vec3.fromArray(b, vertices, bi)
  71. Vec3.fromArray(c, vertices, ci)
  72. Vec3.sub(cb, c, b)
  73. Vec3.sub(ab, a, b)
  74. Vec3.cross(cb, cb, ab)
  75. normals[ ai ] += cb[ 0 ]
  76. normals[ ai + 1 ] += cb[ 1 ]
  77. normals[ ai + 2 ] += cb[ 2 ]
  78. normals[ bi ] += cb[ 0 ]
  79. normals[ bi + 1 ] += cb[ 1 ]
  80. normals[ bi + 2 ] += cb[ 2 ]
  81. normals[ ci ] += cb[ 0 ]
  82. normals[ ci + 1 ] += cb[ 1 ]
  83. normals[ ci + 2 ] += cb[ 2 ]
  84. }
  85. normalizeVec3Array(normals)
  86. return normals
  87. }
  88. /** vertex normals for unindexed triangle soup, normal array must contain only zeros */
  89. export function computeVertexNormals<T extends Helpers.NumberArray> (vertices: Helpers.NumberArray, normals: T) {
  90. setArrayZero(normals)
  91. const a = Vec3.zero()
  92. const b = Vec3.zero()
  93. const c = Vec3.zero()
  94. const cb = Vec3.zero()
  95. const ab = Vec3.zero()
  96. for (let i = 0, il = vertices.length; i < il; i += 9) {
  97. Vec3.fromArray(a, vertices, i)
  98. Vec3.fromArray(b, vertices, i + 3)
  99. Vec3.fromArray(c, vertices, i + 6)
  100. Vec3.sub(cb, c, b)
  101. Vec3.sub(ab, a, b)
  102. Vec3.cross(cb, cb, ab)
  103. normals[ i ] = cb[ 0 ]
  104. normals[ i + 1 ] = cb[ 1 ]
  105. normals[ i + 2 ] = cb[ 2 ]
  106. normals[ i + 3 ] = cb[ 0 ]
  107. normals[ i + 4 ] = cb[ 1 ]
  108. normals[ i + 5 ] = cb[ 2 ]
  109. normals[ i + 6 ] = cb[ 0 ]
  110. normals[ i + 7 ] = cb[ 1 ]
  111. normals[ i + 8 ] = cb[ 2 ]
  112. }
  113. normalizeVec3Array(normals)
  114. return normals
  115. }