1
1
import {
2
- onMounted ,
3
2
ref ,
4
3
shallowRef ,
5
4
nextTick ,
8
7
createVNode ,
9
8
render ,
10
9
h ,
11
- type DefineComponent ,
12
10
} from 'vue'
13
11
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
14
12
import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js'
@@ -21,10 +19,8 @@ import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'
21
19
import { isFunction } from 'lodash'
22
20
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'
23
21
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'
24
- import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'
25
22
import { OutlinePass } from 'three/addons/postprocessing/OutlinePass.js'
26
23
import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'
27
- import { FXAAShader } from 'three/addons/shaders/FXAAShader.js'
28
24
// import TWEEN from '@tweenjs/tween.js'
29
25
import TWEEN from 'three/examples/jsm/libs/tween.module.js'
30
26
import * as THREE from 'three'
@@ -45,6 +41,7 @@ export function useThree() {
45
41
const ocontrol = shallowRef < OrbitControls > ( ) //轨道控制器
46
42
const tcontrol = shallowRef < TransformControls > ( ) //变换控制器
47
43
const outlinePass = shallowRef < OutlinePass > ( ) //outlinePass
44
+ const hexPass = shallowRef ( )
48
45
const composers = new Map ( ) //后期处理
49
46
const mixers : any = [ ] //动画混合器
50
47
const clock = new THREE . Clock ( ) //时钟
@@ -61,6 +58,8 @@ export function useThree() {
61
58
boostrapLights ( )
62
59
onAnimate ( )
63
60
onWindowResize ( )
61
+ addOutlineEffect ( )
62
+ addHexEffect ( )
64
63
}
65
64
//Scene
66
65
const boostrapScene = ( ) => {
@@ -202,7 +201,7 @@ export function useThree() {
202
201
render ( instance , document . createElement ( 'div' ) )
203
202
return instance . el
204
203
}
205
- const element = crender ( component , props )
204
+ const element = crender ( component , props ) as HTMLElement
206
205
const css2dObject = new CSS2DObject ( element )
207
206
return css2dObject
208
207
}
@@ -268,7 +267,15 @@ export function useThree() {
268
267
} )
269
268
}
270
269
//添加outline效果
271
- const addOutlineEffect = ( ) => {
270
+ const addOutlineEffect = ( config ?: {
271
+ edgeStrength ?: number
272
+ edgeGlow ?: number
273
+ edgeThickness ?: number
274
+ pulsePeriod ?: number
275
+ usePatternTexture ?: boolean
276
+ visibleEdgeColor ?: string | number
277
+ hiddenEdgeColor ?: string | number
278
+ } ) => {
272
279
const composer = new EffectComposer ( renderer . value ! )
273
280
const renderPass = new RenderPass ( scene . value ! , camera . value ! )
274
281
composer . addPass ( renderPass )
@@ -277,17 +284,49 @@ export function useThree() {
277
284
scene . value ! ,
278
285
camera . value !
279
286
)
280
- outlinePass . value . edgeStrength = 3
281
- outlinePass . value . edgeGlow = 1
282
- outlinePass . value . edgeThickness = 4
283
- outlinePass . value . visibleEdgeColor . set ( '#0efaa6' )
284
- outlinePass . value . hiddenEdgeColor . set ( '#0efaa6' )
287
+ const deafultConfig = {
288
+ edgeStrength : 3 ,
289
+ edgeGlow : 0 ,
290
+ edgeThickness : 1 ,
291
+ pulsePeriod : 0 ,
292
+ usePatternTexture : false ,
293
+ visibleEdgeColor : '#fff' ,
294
+ hiddenEdgeColor : '#fff' ,
295
+ }
296
+ const op = Object . assign ( { } , deafultConfig , config )
297
+
298
+ outlinePass . value . edgeStrength = op . edgeStrength
299
+ outlinePass . value . edgeGlow = op . edgeGlow
300
+ outlinePass . value . edgeThickness = op . edgeThickness
301
+ outlinePass . value . visibleEdgeColor . set ( op . visibleEdgeColor )
302
+ outlinePass . value . hiddenEdgeColor . set ( op . hiddenEdgeColor )
285
303
outlinePass . value . selectedObjects = [ ]
286
304
composer . addPass ( outlinePass . value )
287
305
const outputPass = new OutputPass ( )
288
306
composer . addPass ( outputPass )
289
307
composers . set ( 'outline' , composer )
290
308
}
309
+ //添加outline效果
310
+ const addHexEffect = ( color ?: number | string ) => {
311
+ let selected : any [ ] = [ ]
312
+ hexPass . value = {
313
+ get selectedObjects ( ) {
314
+ return selected
315
+ } ,
316
+ set selectedObjects ( val ) {
317
+ //先清空之前的
318
+ selected . forEach ( ( mesh ) => {
319
+ if ( mesh . material ) mesh . material . emissive . setHex ( mesh . hex )
320
+ } )
321
+ val . forEach ( ( mesh ) => {
322
+ mesh . material = mesh . material . clone ( )
323
+ mesh . hex = mesh . material . emissive . getHex ( )
324
+ mesh . material . emissive . setHex ( color ?? 0x888888 )
325
+ } )
326
+ selected = [ ...val ]
327
+ } ,
328
+ }
329
+ }
291
330
292
331
// 模型拾取
293
332
const addModelPick = (
@@ -315,6 +354,32 @@ export function useThree() {
315
354
onUnmounted ( ( ) => document . removeEventListener ( 'click' , handler ) )
316
355
}
317
356
357
+ // 模型悬浮拾取
358
+ const addModelHoverPick = (
359
+ object : THREE . Object3D ,
360
+ callback : (
361
+ intersects :
362
+ | THREE . Intersection < THREE . Object3D < THREE . Object3DEventMap > > [ ]
363
+ | [ ]
364
+ ) => void
365
+ ) => {
366
+ const handler = ( event : MouseEvent ) => {
367
+ const el = container . value as HTMLElement
368
+ const rect = el . getBoundingClientRect ( )
369
+ const mouse = new THREE . Vector2 (
370
+ ( ( event . clientX - rect . left ) / rect . width ) * 2 - 1 ,
371
+ - ( ( event . clientY - rect . top ) / rect . height ) * 2 + 1
372
+ )
373
+ const raycaster = new THREE . Raycaster ( )
374
+ raycaster . setFromCamera ( mouse , camera . value ! )
375
+ const intersects = raycaster . intersectObject ( object , true )
376
+ isFunction ( callback ) && callback ( intersects )
377
+ // if (intersects.length <= 0) return void 0
378
+ }
379
+ document . addEventListener ( 'mousemove' , handler )
380
+ onUnmounted ( ( ) => document . removeEventListener ( 'mousemove' , handler ) )
381
+ }
382
+
318
383
nextTick ( ( ) => {
319
384
boostrap ( )
320
385
} )
@@ -331,6 +396,7 @@ export function useThree() {
331
396
renderMixins,
332
397
composers,
333
398
outlinePass,
399
+ hexPass,
334
400
loadGltf,
335
401
loadAnimationMixer,
336
402
loadAxesHelper,
@@ -339,7 +405,9 @@ export function useThree() {
339
405
transitionAnimation,
340
406
planeClippingAnimation,
341
407
addModelPick,
408
+ addModelHoverPick,
342
409
addOutlineEffect,
410
+ addHexEffect,
343
411
}
344
412
}
345
413
0 commit comments