Skip to content

Commit cfa8803

Browse files
committed
fix: WebComponent ViewCube updated to support edge and corner hotspots
- We now merged the webgl ViewCube with the WebComponent ViewCube.
1 parent 9be147a commit cfa8803

File tree

4 files changed

+105
-318
lines changed

4 files changed

+105
-318
lines changed

src/Handles/ViewCube.ts

Lines changed: 3 additions & 185 deletions
Original file line numberDiff line numberDiff line change
@@ -243,205 +243,23 @@ class ViewCube extends TreeItem {
243243
}
244244
}
245245

246-
bindToViewport(renderer: GLRenderer, viewport: GLViewport, pixelOffset = 200, screenSpaceCoord: number[] = [1, 1]) {
247-
renderer.addTreeItem(this)
248-
this.viewport = viewport
249-
const camera = this.viewport.getCamera()
250-
251-
const updateXfo = () => {
252-
const focalDistance = camera.focalDistanceParam.value
253-
const xfo = new Xfo()
254-
255-
const pos = new Vec3()
256-
const fov = camera.fovParam.value
257-
const viewHeightPersp = Math.tan(fov * 0.5) * focalDistance
258-
259-
// @ts-ignore
260-
const viewHeightOrth = camera.viewHeight * 0.5
261-
const halfViewHeight = MathFunctions.lerp(viewHeightPersp, viewHeightOrth, camera.isOrthographicParam.value)
262-
263-
const width = viewport.getWidth() / window.devicePixelRatio
264-
const height = viewport.getHeight() / window.devicePixelRatio
265-
const aspectRatio = width / height
266-
const halfViewWidth = halfViewHeight * aspectRatio
267-
268-
const margin = pixelOffset * (halfViewHeight / height)
269-
pos.set(
270-
(halfViewWidth - margin) * screenSpaceCoord[0],
271-
(halfViewHeight - margin) * screenSpaceCoord[1],
272-
-focalDistance
273-
)
274-
275-
// normalize the hight so it is the same size on all screen resolutions.
276-
// the 60 is just a magic number to make the view cube a nice size with a 1.0
277-
// size parameter.
278-
const sc = (halfViewHeight * 2.0) / (height / 50)
279-
280-
xfo.tr = camera.globalXfoParam.value.transformVec3(pos)
281-
xfo.sc.set(sc, sc, sc)
282-
this.globalXfoParam.value = xfo
283-
}
284-
285-
updateXfo()
286-
camera.on('projectionParamChanged', updateXfo)
287-
camera.globalXfoParam.on('valueChanged', updateXfo)
288-
viewport.on('resized', updateXfo)
289-
}
290-
291-
// ///////////////////////////////////
292-
// Mouse events
293-
294-
alignToVector(normal: Vec3, duration = 400) {
295-
const camera = this.viewport.getCamera()
296-
297-
const target = camera.getTargetPosition()
298-
const dist = camera.getFocalDistance()
299-
300-
const startXfo = camera.globalXfoParam.value
301-
const startUp = startXfo.ori.getYaxis()
302-
startUp.subtractInPlace(normal.scale(startUp.dot(normal)))
303-
304-
const endUp = new Vec3()
305-
const calcUpVector = () => {
306-
if (Math.abs(startUp.x) > Math.abs(startUp.y) && Math.abs(startUp.x) > Math.abs(startUp.z)) {
307-
if (startUp.x > 0) endUp.x = 1
308-
else endUp.x = -1
309-
} else if (Math.abs(startUp.y) > Math.abs(startUp.x) && Math.abs(startUp.y) > Math.abs(startUp.z)) {
310-
if (startUp.y > 0) endUp.y = 1
311-
else endUp.y = -1
312-
} else if (Math.abs(startUp.z) > Math.abs(startUp.x) && Math.abs(startUp.z) > Math.abs(startUp.y)) {
313-
if (startUp.z > 0) endUp.z = 1
314-
else endUp.z = -1
315-
} else {
316-
console.warn('Invalid Starting Camera Xfo')
317-
endUp.z = 1
318-
}
319-
}
320-
321-
let manipulator = this.viewport.getManipulator()
322-
if (manipulator instanceof ToolManager) {
323-
const toolManager: ToolManager = manipulator
324-
if ('CameraManipulator' in toolManager.tools) {
325-
manipulator = toolManager.tools['CameraManipulator']
326-
} else {
327-
for (let key in toolManager.tools) {
328-
if (toolManager.tools[key] instanceof CameraManipulator) {
329-
manipulator = toolManager.tools[key]
330-
break
331-
}
332-
}
333-
}
334-
}
335-
if (manipulator instanceof CameraManipulator) {
336-
if (manipulator.defaultManipulationState == CameraManipulator.MANIPULATION_MODES.turntable) {
337-
if (normal.approxEqual(new Vec3(0, 0, 1)) || normal.approxEqual(new Vec3(0, 0, -1))) {
338-
calcUpVector()
339-
} else {
340-
endUp.z = 1
341-
}
342-
} else {
343-
calcUpVector()
344-
}
345-
} else {
346-
calcUpVector()
347-
}
348-
349-
// Calculate the target orientation of the camera.
350-
const endOri = new Quat()
351-
endOri.setFromDirectionAndUpvector(normal, endUp)
352-
endOri.alignWith(startXfo.ori)
353-
354-
// const endOrtho = 0 //this.viewport. ? 0 : 1
355-
// if (endOrtho > 0.5 && startOrtho < 0.5) {
356-
// // IF we are transitioning to an orthographic projection, we match the orthographic
357-
// // view height with the current perspective projection height at the target distance.
358-
// // This keeps the framing consistent as we change the camera.
359-
// //@ts-ignore
360-
// camera.viewHeight = Math.sin(camera.fovParam.value * 0.5) * dist * 2
361-
// }
362-
363-
// ////////////////////////////////////////////////////
364-
// Now blend the camera from the starting values to the end values.
365-
366-
const count = Math.round(duration / 20) // each step is 20ms
367-
let id
368-
let i = 1
369-
const applyMovement = () => {
370-
const lerpValue = MathFunctions.smoothStep(0, 1, i / count)
371-
372-
// interpolate the orientation between the start and the end ones.
373-
const xfo = new Xfo()
374-
xfo.ori = startXfo.ori.slerp(endOri, lerpValue).normalize()
375-
376-
// Move the camera back away from the new target using the orientation.
377-
const newDir = xfo.ori.getZaxis().negate()
378-
xfo.tr = target.subtract(newDir.scale(dist))
379-
380-
camera.globalXfoParam.setValue(xfo)
381-
382-
i++
383-
if (i <= count) {
384-
id = setTimeout(applyMovement, 20)
385-
} else {
386-
// This event tells the viewport to re-render the picking buffer.
387-
camera.emit('movementFinished')
388-
}
389-
}
390-
applyMovement()
391-
}
392-
393-
/**
394-
* Event fired when a pointing device button is pressed while the pointer is over the handle element.
395-
*
396-
* @param event - The event param.
397-
*/
398-
onPointerDown(event: ZeaPointerEvent): void {
399-
event.stopPropagation()
400-
}
401-
402-
/**
403-
* Event fired when a pointing device is moved while the cursor's hotspot is over the handle.
404-
*
405-
* @param event - The event param.
406-
*/
407-
onPointerMove(event: ZeaPointerEvent): void {
408-
event.stopPropagation()
246+
setFaceColor(faceColor: Color, faceHighlightColor: Color): void {
247+
this.normalMaterial.baseColorParam.value = faceColor
248+
this.highlightedMaterial.baseColorParam.value = faceHighlightColor
409249
}
410250

411-
/**
412-
* Event fired when a pointing device is moved while the cursor's hotspot is over the handle.
413-
*
414-
* @param event - The event param.
415-
*/
416251
onPointerEnter(event: ZeaPointerEvent): void {
417252
event.stopPropagation()
418253

419254
this.highlightedGeom = event.intersectionData!.geomItem as GeomItem
420255
this.highlightedGeom.materialParam.value = this.highlightedMaterial
421256
}
422257

423-
/**
424-
* Event fired when a pointing device is moved while the cursor's hotspot is over the handle.
425-
*
426-
* @param event - The event param.
427-
*/
428258
onPointerLeave(event: ZeaPointerEvent): void {
429259
event.stopPropagation()
430260

431261
this.highlightedGeom.materialParam.value = this.normalMaterial
432262
}
433-
434-
/**
435-
* Event fired when a pointing device button is released while the pointer is over the handle.
436-
*
437-
* @param event - The event param.
438-
*/
439-
onPointerClick(event: ZeaPointerEvent): void {
440-
const geomItem = event.intersectionData!.geomItem
441-
const vec = geomItem.globalXfoParam.value.ori.rotateVec3(new Vec3(0, 0, 1))
442-
this.alignToVector(vec)
443-
event.stopPropagation()
444-
}
445263
}
446264

447265
export { ViewCube }

src/Handles/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,5 @@ export * from './ArcSlider.js'
66
export * from './ScreenSpaceMovementHandle.js'
77
export * from './XfoHandle'
88
export * from './AxisTripod'
9-
export * from './ViewCube'
109

1110
export * from './Shaders/HandleMaterial'

0 commit comments

Comments
 (0)