threepipe
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import {Object3D, PerspectiveCamera, Scene, Vector3} from 'three'
  2. import {Box3B} from '../math/Box3B'
  3. import {IWebGLRenderer} from '../../core'
  4. /**
  5. * Returns a snapshot of the object.
  6. * Does a simple render, does not run the full pipeline.
  7. *
  8. * Ideally, call this from preRender and object must be in root, for usage see {@link MaterialPreviewGenerator}.
  9. * @param renderer
  10. * @param object
  11. * @param root
  12. * @param channel
  13. * @param camOffset
  14. * @param camera
  15. */
  16. export function snapObject(
  17. renderer: IWebGLRenderer,
  18. object: Object3D,
  19. root?: Scene,
  20. channel = 7,
  21. camOffset = new Vector3(0, 0, 1.5),
  22. camera = new PerspectiveCamera(45, 1, 0.1, 1000)
  23. ): string {
  24. const oldVisible = object.visible
  25. object.visible = true
  26. const bbox = new Box3B().expandByObject(object, true, true)
  27. const center = bbox.getCenter(new Vector3())
  28. const bboxSize = bbox.getSize(new Vector3())
  29. camera.position.copy(center).add(camOffset.clone().multiplyScalar(Math.max(bboxSize.x, bboxSize.y, bboxSize.z)))
  30. camera.lookAt(center)
  31. if (object) {
  32. object.traverseVisible(obj => {
  33. obj.layers.enable(channel)
  34. })
  35. // console.log((object as any).material)
  36. }
  37. if (channel > 0)
  38. camera.layers.set(channel)
  39. else
  40. camera.layers.enableAll()
  41. // scene.environment = this.viewer.scene.getEnvironment() as any
  42. renderer.setRenderTarget(null)
  43. renderer.clear()
  44. if (typeof renderer.renderWithModes === 'function') {
  45. renderer.renderWithModes({
  46. backgroundRender: false,
  47. // mainRenderPass: false,
  48. // screenSpaceRendering: false,
  49. // shadowMapRender: false,
  50. }, ()=>{
  51. renderer.render(root ?? object, camera)
  52. })
  53. } else {
  54. renderer.render(root ?? object, camera)
  55. }
  56. // renderer.setRenderTarget(target)
  57. // this._renderer.render(root, camera)
  58. // todo use webp when possible.
  59. const snap = renderer.domElement.toDataURL('image/png')
  60. renderer.clear()
  61. object.visible = oldVisible
  62. object.traverseVisible(obj => {
  63. obj.layers.disable(channel)
  64. })
  65. camera.layers.enableAll()
  66. return snap
  67. }