util.ts 4.0 KB

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