THREE.MeshLine.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  1. ;(function() {
  2. 'use strict'
  3. var root = this
  4. var has_require = typeof require !== 'undefined'
  5. var THREE = root.THREE || (has_require && require('three'))
  6. if (!THREE) throw new Error('MeshLine requires three.js')
  7. function MeshLine() {
  8. THREE.BufferGeometry.call(this)
  9. this.type = 'MeshLine'
  10. this.positions = []
  11. this.previous = []
  12. this.next = []
  13. this.side = []
  14. this.width = []
  15. this.indices_array = []
  16. this.uvs = []
  17. this.counters = []
  18. this._points = []
  19. this._geom = null
  20. this.widthCallback = null
  21. // Used to raycast
  22. this.matrixWorld = new THREE.Matrix4()
  23. Object.defineProperties(this, {
  24. // this is now a bufferGeometry
  25. // add getter to support previous api
  26. geometry: {
  27. enumerable: true,
  28. get: function() {
  29. return this
  30. },
  31. },
  32. geom: {
  33. enumerable: true,
  34. get: function() {
  35. return this._geom
  36. },
  37. set: function(value) {
  38. this.setGeometry(value, this.widthCallback)
  39. },
  40. },
  41. // for declaritive architectures
  42. // to return the same value that sets the points
  43. // eg. this.points = points
  44. // console.log(this.points) -> points
  45. points: {
  46. enumerable: true,
  47. get: function() {
  48. return this._points
  49. },
  50. set: function(value) {
  51. this.setPoints(value, this.widthCallback)
  52. },
  53. },
  54. })
  55. }
  56. MeshLine.prototype = Object.create(THREE.BufferGeometry.prototype)
  57. MeshLine.prototype.constructor = MeshLine
  58. MeshLine.prototype.isMeshLine = true
  59. MeshLine.prototype.setMatrixWorld = function(matrixWorld) {
  60. this.matrixWorld = matrixWorld
  61. }
  62. // setting via a geometry is rather superfluous
  63. // as you're creating a unecessary geometry just to throw away
  64. // but exists to support previous api
  65. MeshLine.prototype.setGeometry = function(g, c) {
  66. // as the input geometry are mutated we store them
  67. // for later retreival when necessary (declaritive architectures)
  68. this._geometry = g;
  69. if (g instanceof THREE.Geometry) {
  70. this.setPoints(g.vertices, c);
  71. } else if (g instanceof THREE.BufferGeometry) {
  72. this.setPoints(g.getAttribute("position").array, c);
  73. } else {
  74. this.setPoints(g, c);
  75. }
  76. }
  77. MeshLine.prototype.setPoints = function(points, wcb) {
  78. if (!(points instanceof Float32Array) && !(points instanceof Array)) {
  79. console.error(
  80. "ERROR: The BufferArray of points is not instancied correctly."
  81. );
  82. return;
  83. }
  84. // as the points are mutated we store them
  85. // for later retreival when necessary (declaritive architectures)
  86. this._points = points;
  87. this.widthCallback = wcb;
  88. this.positions = [];
  89. this.counters = [];
  90. if (points.length && points[0] instanceof THREE.Vector3) {
  91. // could transform Vector3 array into the array used below
  92. // but this approach will only loop through the array once
  93. // and is more performant
  94. for (var j = 0; j < points.length; j++) {
  95. var p = points[j];
  96. var c = j / points.length;
  97. this.positions.push(p.x, p.y, p.z);
  98. this.positions.push(p.x, p.y, p.z);
  99. this.counters.push(c);
  100. this.counters.push(c);
  101. }
  102. } else {
  103. for (var j = 0; j < points.length; j += 3) {
  104. var c = j / points.length;
  105. this.positions.push(points[j], points[j + 1], points[j + 2]);
  106. this.positions.push(points[j], points[j + 1], points[j + 2]);
  107. this.counters.push(c);
  108. this.counters.push(c);
  109. }
  110. }
  111. this.process();
  112. }
  113. function MeshLineRaycast(raycaster, intersects) {
  114. var inverseMatrix = new THREE.Matrix4()
  115. var ray = new THREE.Ray()
  116. var sphere = new THREE.Sphere()
  117. var interRay = new THREE.Vector3()
  118. var geometry = this.geometry
  119. // Checking boundingSphere distance to ray
  120. sphere.copy(geometry.boundingSphere)
  121. sphere.applyMatrix4(this.matrixWorld)
  122. if (raycaster.ray.intersectSphere(sphere, interRay) === false) {
  123. return
  124. }
  125. inverseMatrix.getInverse(this.matrixWorld)
  126. ray.copy(raycaster.ray).applyMatrix4(inverseMatrix)
  127. var vStart = new THREE.Vector3()
  128. var vEnd = new THREE.Vector3()
  129. var interSegment = new THREE.Vector3()
  130. var step = this instanceof THREE.LineSegments ? 2 : 1
  131. var index = geometry.index
  132. var attributes = geometry.attributes
  133. if (index !== null) {
  134. var indices = index.array
  135. var positions = attributes.position.array
  136. var widths = attributes.width.array
  137. for (var i = 0, l = indices.length - 1; i < l; i += step) {
  138. var a = indices[i]
  139. var b = indices[i + 1]
  140. vStart.fromArray(positions, a * 3)
  141. vEnd.fromArray(positions, b * 3)
  142. var width = widths[Math.floor(i / 3)] != undefined ? widths[Math.floor(i / 3)] : 1
  143. var precision = raycaster.params.Line.threshold + (this.material.lineWidth * width) / 2
  144. var precisionSq = precision * precision
  145. var distSq = ray.distanceSqToSegment(vStart, vEnd, interRay, interSegment)
  146. if (distSq > precisionSq) continue
  147. interRay.applyMatrix4(this.matrixWorld) //Move back to world space for distance calculation
  148. var distance = raycaster.ray.origin.distanceTo(interRay)
  149. if (distance < raycaster.near || distance > raycaster.far) continue
  150. intersects.push({
  151. distance: distance,
  152. // What do we want? intersection point on the ray or on the segment??
  153. // point: raycaster.ray.at( distance ),
  154. point: interSegment.clone().applyMatrix4(this.matrixWorld),
  155. index: i,
  156. face: null,
  157. faceIndex: null,
  158. object: this,
  159. })
  160. // make event only fire once
  161. i = l
  162. }
  163. }
  164. }
  165. MeshLine.prototype.raycast = MeshLineRaycast
  166. MeshLine.prototype.compareV3 = function(a, b) {
  167. var aa = a * 6
  168. var ab = b * 6
  169. return (
  170. this.positions[aa] === this.positions[ab] &&
  171. this.positions[aa + 1] === this.positions[ab + 1] &&
  172. this.positions[aa + 2] === this.positions[ab + 2]
  173. )
  174. }
  175. MeshLine.prototype.copyV3 = function(a) {
  176. var aa = a * 6
  177. return [this.positions[aa], this.positions[aa + 1], this.positions[aa + 2]]
  178. }
  179. MeshLine.prototype.process = function() {
  180. var l = this.positions.length / 6
  181. this.previous = []
  182. this.next = []
  183. this.side = []
  184. this.width = []
  185. this.indices_array = []
  186. this.uvs = []
  187. var w
  188. var v
  189. // initial previous points
  190. if (this.compareV3(0, l - 1)) {
  191. v = this.copyV3(l - 2)
  192. } else {
  193. v = this.copyV3(0)
  194. }
  195. this.previous.push(v[0], v[1], v[2])
  196. this.previous.push(v[0], v[1], v[2])
  197. for (var j = 0; j < l; j++) {
  198. // sides
  199. this.side.push(1)
  200. this.side.push(-1)
  201. // widths
  202. if (this.widthCallback) w = this.widthCallback(j / (l - 1))
  203. else w = 1
  204. this.width.push(w)
  205. this.width.push(w)
  206. // uvs
  207. this.uvs.push(j / (l - 1), 0)
  208. this.uvs.push(j / (l - 1), 1)
  209. if (j < l - 1) {
  210. // points previous to poisitions
  211. v = this.copyV3(j)
  212. this.previous.push(v[0], v[1], v[2])
  213. this.previous.push(v[0], v[1], v[2])
  214. // indices
  215. var n = j * 2
  216. this.indices_array.push(n, n + 1, n + 2)
  217. this.indices_array.push(n + 2, n + 1, n + 3)
  218. }
  219. if (j > 0) {
  220. // points after poisitions
  221. v = this.copyV3(j)
  222. this.next.push(v[0], v[1], v[2])
  223. this.next.push(v[0], v[1], v[2])
  224. }
  225. }
  226. // last next point
  227. if (this.compareV3(l - 1, 0)) {
  228. v = this.copyV3(1)
  229. } else {
  230. v = this.copyV3(l - 1)
  231. }
  232. this.next.push(v[0], v[1], v[2])
  233. this.next.push(v[0], v[1], v[2])
  234. // redefining the attribute seems to prevent range errors
  235. // if the user sets a differing number of vertices
  236. if (!this._attributes || this._attributes.position.count !== this.positions.length) {
  237. this._attributes = {
  238. position: new THREE.BufferAttribute(new Float32Array(this.positions), 3),
  239. previous: new THREE.BufferAttribute(new Float32Array(this.previous), 3),
  240. next: new THREE.BufferAttribute(new Float32Array(this.next), 3),
  241. side: new THREE.BufferAttribute(new Float32Array(this.side), 1),
  242. width: new THREE.BufferAttribute(new Float32Array(this.width), 1),
  243. uv: new THREE.BufferAttribute(new Float32Array(this.uvs), 2),
  244. index: new THREE.BufferAttribute(new Uint16Array(this.indices_array), 1),
  245. counters: new THREE.BufferAttribute(new Float32Array(this.counters), 1),
  246. }
  247. } else {
  248. this._attributes.position.copyArray(new Float32Array(this.positions))
  249. this._attributes.position.needsUpdate = true
  250. this._attributes.previous.copyArray(new Float32Array(this.previous))
  251. this._attributes.previous.needsUpdate = true
  252. this._attributes.next.copyArray(new Float32Array(this.next))
  253. this._attributes.next.needsUpdate = true
  254. this._attributes.side.copyArray(new Float32Array(this.side))
  255. this._attributes.side.needsUpdate = true
  256. this._attributes.width.copyArray(new Float32Array(this.width))
  257. this._attributes.width.needsUpdate = true
  258. this._attributes.uv.copyArray(new Float32Array(this.uvs))
  259. this._attributes.uv.needsUpdate = true
  260. this._attributes.index.copyArray(new Uint16Array(this.indices_array))
  261. this._attributes.index.needsUpdate = true
  262. }
  263. this.setAttribute('position', this._attributes.position)
  264. this.setAttribute('previous', this._attributes.previous)
  265. this.setAttribute('next', this._attributes.next)
  266. this.setAttribute('side', this._attributes.side)
  267. this.setAttribute('width', this._attributes.width)
  268. this.setAttribute('uv', this._attributes.uv)
  269. this.setAttribute('counters', this._attributes.counters)
  270. this.setIndex(this._attributes.index)
  271. this.computeBoundingSphere()
  272. this.computeBoundingBox()
  273. }
  274. function memcpy(src, srcOffset, dst, dstOffset, length) {
  275. var i
  276. src = src.subarray || src.slice ? src : src.buffer
  277. dst = dst.subarray || dst.slice ? dst : dst.buffer
  278. src = srcOffset
  279. ? src.subarray
  280. ? src.subarray(srcOffset, length && srcOffset + length)
  281. : src.slice(srcOffset, length && srcOffset + length)
  282. : src
  283. if (dst.set) {
  284. dst.set(src, dstOffset)
  285. } else {
  286. for (i = 0; i < src.length; i++) {
  287. dst[i + dstOffset] = src[i]
  288. }
  289. }
  290. return dst
  291. }
  292. /**
  293. * Fast method to advance the line by one position. The oldest position is removed.
  294. * @param position
  295. */
  296. MeshLine.prototype.advance = function(position) {
  297. var positions = this._attributes.position.array
  298. var previous = this._attributes.previous.array
  299. var next = this._attributes.next.array
  300. var l = positions.length
  301. // PREVIOUS
  302. memcpy(positions, 0, previous, 0, l)
  303. // POSITIONS
  304. memcpy(positions, 6, positions, 0, l - 6)
  305. positions[l - 6] = position.x
  306. positions[l - 5] = position.y
  307. positions[l - 4] = position.z
  308. positions[l - 3] = position.x
  309. positions[l - 2] = position.y
  310. positions[l - 1] = position.z
  311. // NEXT
  312. memcpy(positions, 6, next, 0, l - 6)
  313. next[l - 6] = position.x
  314. next[l - 5] = position.y
  315. next[l - 4] = position.z
  316. next[l - 3] = position.x
  317. next[l - 2] = position.y
  318. next[l - 1] = position.z
  319. this._attributes.position.needsUpdate = true
  320. this._attributes.previous.needsUpdate = true
  321. this._attributes.next.needsUpdate = true
  322. }
  323. THREE.ShaderChunk['meshline_vert'] = [
  324. '',
  325. THREE.ShaderChunk.logdepthbuf_pars_vertex,
  326. THREE.ShaderChunk.fog_pars_vertex,
  327. '',
  328. 'attribute vec3 previous;',
  329. 'attribute vec3 next;',
  330. 'attribute float side;',
  331. 'attribute float width;',
  332. 'attribute float counters;',
  333. '',
  334. 'uniform vec2 resolution;',
  335. 'uniform float lineWidth;',
  336. 'uniform vec3 color;',
  337. 'uniform float opacity;',
  338. 'uniform float sizeAttenuation;',
  339. '',
  340. 'varying vec2 vUV;',
  341. 'varying vec4 vColor;',
  342. 'varying float vCounters;',
  343. '',
  344. 'vec2 fix( vec4 i, float aspect ) {',
  345. '',
  346. ' vec2 res = i.xy / i.w;',
  347. ' res.x *= aspect;',
  348. ' vCounters = counters;',
  349. ' return res;',
  350. '',
  351. '}',
  352. '',
  353. 'void main() {',
  354. '',
  355. ' float aspect = resolution.x / resolution.y;',
  356. '',
  357. ' vColor = vec4( color, opacity );',
  358. ' vUV = uv;',
  359. '',
  360. ' mat4 m = projectionMatrix * modelViewMatrix;',
  361. ' vec4 finalPosition = m * vec4( position, 1.0 );',
  362. ' vec4 prevPos = m * vec4( previous, 1.0 );',
  363. ' vec4 nextPos = m * vec4( next, 1.0 );',
  364. '',
  365. ' vec2 currentP = fix( finalPosition, aspect );',
  366. ' vec2 prevP = fix( prevPos, aspect );',
  367. ' vec2 nextP = fix( nextPos, aspect );',
  368. '',
  369. ' float w = lineWidth * width;',
  370. '',
  371. ' vec2 dir;',
  372. ' if( nextP == currentP ) dir = normalize( currentP - prevP );',
  373. ' else if( prevP == currentP ) dir = normalize( nextP - currentP );',
  374. ' else {',
  375. ' vec2 dir1 = normalize( currentP - prevP );',
  376. ' vec2 dir2 = normalize( nextP - currentP );',
  377. ' dir = normalize( dir1 + dir2 );',
  378. '',
  379. ' vec2 perp = vec2( -dir1.y, dir1.x );',
  380. ' vec2 miter = vec2( -dir.y, dir.x );',
  381. ' //w = clamp( w / dot( miter, perp ), 0., 4. * lineWidth * width );',
  382. '',
  383. ' }',
  384. '',
  385. ' //vec2 normal = ( cross( vec3( dir, 0. ), vec3( 0., 0., 1. ) ) ).xy;',
  386. ' vec4 normal = vec4( -dir.y, dir.x, 0., 1. );',
  387. ' normal.xy *= .5 * w;',
  388. ' normal *= projectionMatrix;',
  389. ' if( sizeAttenuation == 0. ) {',
  390. ' normal.xy *= finalPosition.w;',
  391. ' normal.xy /= ( vec4( resolution, 0., 1. ) * projectionMatrix ).xy;',
  392. ' }',
  393. '',
  394. ' finalPosition.xy += normal.xy * side;',
  395. '',
  396. ' gl_Position = finalPosition;',
  397. '',
  398. THREE.ShaderChunk.logdepthbuf_vertex,
  399. THREE.ShaderChunk.fog_vertex && ' vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );',
  400. THREE.ShaderChunk.fog_vertex,
  401. '}',
  402. ].join('\n')
  403. THREE.ShaderChunk['meshline_frag'] = [
  404. '',
  405. THREE.ShaderChunk.fog_pars_fragment,
  406. THREE.ShaderChunk.logdepthbuf_pars_fragment,
  407. '',
  408. 'uniform sampler2D map;',
  409. 'uniform sampler2D alphaMap;',
  410. 'uniform float useMap;',
  411. 'uniform float useAlphaMap;',
  412. 'uniform float useDash;',
  413. 'uniform float dashArray;',
  414. 'uniform float dashOffset;',
  415. 'uniform float dashRatio;',
  416. 'uniform float visibility;',
  417. 'uniform float alphaTest;',
  418. 'uniform vec2 repeat;',
  419. '',
  420. 'varying vec2 vUV;',
  421. 'varying vec4 vColor;',
  422. 'varying float vCounters;',
  423. '',
  424. 'void main() {',
  425. '',
  426. THREE.ShaderChunk.logdepthbuf_fragment,
  427. '',
  428. ' vec4 c = vColor;',
  429. ' if( useMap == 1. ) c *= texture2D( map, vUV * repeat );',
  430. ' if( useAlphaMap == 1. ) c.a *= texture2D( alphaMap, vUV * repeat ).a;',
  431. ' if( c.a < alphaTest ) discard;',
  432. ' if( useDash == 1. ){',
  433. ' c.a *= ceil(mod(vCounters + dashOffset, dashArray) - (dashArray * dashRatio));',
  434. ' }',
  435. ' gl_FragColor = c;',
  436. ' gl_FragColor.a *= step(vCounters, visibility);',
  437. '',
  438. THREE.ShaderChunk.fog_fragment,
  439. '}',
  440. ].join('\n')
  441. function MeshLineMaterial(parameters) {
  442. THREE.ShaderMaterial.call(this, {
  443. uniforms: Object.assign({}, THREE.UniformsLib.fog, {
  444. lineWidth: { value: 1 },
  445. map: { value: null },
  446. useMap: { value: 0 },
  447. alphaMap: { value: null },
  448. useAlphaMap: { value: 0 },
  449. color: { value: new THREE.Color(0xffffff) },
  450. opacity: { value: 1 },
  451. resolution: { value: new THREE.Vector2(1, 1) },
  452. sizeAttenuation: { value: 1 },
  453. dashArray: { value: 0 },
  454. dashOffset: { value: 0 },
  455. dashRatio: { value: 0.5 },
  456. useDash: { value: 0 },
  457. visibility: { value: 1 },
  458. alphaTest: { value: 0 },
  459. repeat: { value: new THREE.Vector2(1, 1) },
  460. }),
  461. vertexShader: THREE.ShaderChunk.meshline_vert,
  462. fragmentShader: THREE.ShaderChunk.meshline_frag,
  463. })
  464. this.type = 'MeshLineMaterial'
  465. Object.defineProperties(this, {
  466. lineWidth: {
  467. enumerable: true,
  468. get: function() {
  469. return this.uniforms.lineWidth.value
  470. },
  471. set: function(value) {
  472. this.uniforms.lineWidth.value = value
  473. },
  474. },
  475. map: {
  476. enumerable: true,
  477. get: function() {
  478. return this.uniforms.map.value
  479. },
  480. set: function(value) {
  481. this.uniforms.map.value = value
  482. },
  483. },
  484. useMap: {
  485. enumerable: true,
  486. get: function() {
  487. return this.uniforms.useMap.value
  488. },
  489. set: function(value) {
  490. this.uniforms.useMap.value = value
  491. },
  492. },
  493. alphaMap: {
  494. enumerable: true,
  495. get: function() {
  496. return this.uniforms.alphaMap.value
  497. },
  498. set: function(value) {
  499. this.uniforms.alphaMap.value = value
  500. },
  501. },
  502. useAlphaMap: {
  503. enumerable: true,
  504. get: function() {
  505. return this.uniforms.useAlphaMap.value
  506. },
  507. set: function(value) {
  508. this.uniforms.useAlphaMap.value = value
  509. },
  510. },
  511. color: {
  512. enumerable: true,
  513. get: function() {
  514. return this.uniforms.color.value
  515. },
  516. set: function(value) {
  517. this.uniforms.color.value = value
  518. },
  519. },
  520. opacity: {
  521. enumerable: true,
  522. get: function() {
  523. return this.uniforms.opacity.value
  524. },
  525. set: function(value) {
  526. this.uniforms.opacity.value = value
  527. },
  528. },
  529. resolution: {
  530. enumerable: true,
  531. get: function() {
  532. return this.uniforms.resolution.value
  533. },
  534. set: function(value) {
  535. this.uniforms.resolution.value.copy(value)
  536. },
  537. },
  538. sizeAttenuation: {
  539. enumerable: true,
  540. get: function() {
  541. return this.uniforms.sizeAttenuation.value
  542. },
  543. set: function(value) {
  544. this.uniforms.sizeAttenuation.value = value
  545. },
  546. },
  547. dashArray: {
  548. enumerable: true,
  549. get: function() {
  550. return this.uniforms.dashArray.value
  551. },
  552. set: function(value) {
  553. this.uniforms.dashArray.value = value
  554. this.useDash = value !== 0 ? 1 : 0
  555. },
  556. },
  557. dashOffset: {
  558. enumerable: true,
  559. get: function() {
  560. return this.uniforms.dashOffset.value
  561. },
  562. set: function(value) {
  563. this.uniforms.dashOffset.value = value
  564. },
  565. },
  566. dashRatio: {
  567. enumerable: true,
  568. get: function() {
  569. return this.uniforms.dashRatio.value
  570. },
  571. set: function(value) {
  572. this.uniforms.dashRatio.value = value
  573. },
  574. },
  575. useDash: {
  576. enumerable: true,
  577. get: function() {
  578. return this.uniforms.useDash.value
  579. },
  580. set: function(value) {
  581. this.uniforms.useDash.value = value
  582. },
  583. },
  584. visibility: {
  585. enumerable: true,
  586. get: function() {
  587. return this.uniforms.visibility.value
  588. },
  589. set: function(value) {
  590. this.uniforms.visibility.value = value
  591. },
  592. },
  593. alphaTest: {
  594. enumerable: true,
  595. get: function() {
  596. return this.uniforms.alphaTest.value
  597. },
  598. set: function(value) {
  599. this.uniforms.alphaTest.value = value
  600. },
  601. },
  602. repeat: {
  603. enumerable: true,
  604. get: function() {
  605. return this.uniforms.repeat.value
  606. },
  607. set: function(value) {
  608. this.uniforms.repeat.value.copy(value)
  609. },
  610. },
  611. })
  612. this.setValues(parameters)
  613. }
  614. MeshLineMaterial.prototype = Object.create(THREE.ShaderMaterial.prototype)
  615. MeshLineMaterial.prototype.constructor = MeshLineMaterial
  616. MeshLineMaterial.prototype.isMeshLineMaterial = true
  617. MeshLineMaterial.prototype.copy = function(source) {
  618. THREE.ShaderMaterial.prototype.copy.call(this, source)
  619. this.lineWidth = source.lineWidth
  620. this.map = source.map
  621. this.useMap = source.useMap
  622. this.alphaMap = source.alphaMap
  623. this.useAlphaMap = source.useAlphaMap
  624. this.color.copy(source.color)
  625. this.opacity = source.opacity
  626. this.resolution.copy(source.resolution)
  627. this.sizeAttenuation = source.sizeAttenuation
  628. this.dashArray.copy(source.dashArray)
  629. this.dashOffset.copy(source.dashOffset)
  630. this.dashRatio.copy(source.dashRatio)
  631. this.useDash = source.useDash
  632. this.visibility = source.visibility
  633. this.alphaTest = source.alphaTest
  634. this.repeat.copy(source.repeat)
  635. return this
  636. }
  637. if (typeof exports !== 'undefined') {
  638. if (typeof module !== 'undefined' && module.exports) {
  639. exports = module.exports = {
  640. MeshLine: MeshLine,
  641. MeshLineMaterial: MeshLineMaterial,
  642. MeshLineRaycast: MeshLineRaycast,
  643. }
  644. }
  645. exports.MeshLine = MeshLine
  646. exports.MeshLineMaterial = MeshLineMaterial
  647. exports.MeshLineRaycast = MeshLineRaycast
  648. } else {
  649. root.MeshLine = MeshLine
  650. root.MeshLineMaterial = MeshLineMaterial
  651. root.MeshLineRaycast = MeshLineRaycast
  652. }
  653. }.call(this))