ModelComponent.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import * as THREE from "three";
  2. import shaders from '../Shaders/index'
  3. import ScenesSystem from "../System/ScenesSystem";
  4. import ComponentBase from "../Base/ComponentBase";
  5. export interface IFile {
  6. name: string
  7. buffer?: ArrayBuffer
  8. uv?: ArrayLike<number>
  9. normal?: ArrayLike<number>
  10. position?: ArrayLike<number>
  11. }
  12. export interface IModel {
  13. name: string
  14. transform: {
  15. translation: THREE.Vector3
  16. }
  17. }
  18. export class Model extends THREE.Mesh {
  19. name: string
  20. positionV: THREE.Vector3
  21. material: THREE.ShaderMaterial
  22. showProgress: number
  23. hideProgress: number
  24. private fade: number
  25. private visibility: boolean
  26. private static shaderMaterial = new THREE.ShaderMaterial({
  27. uniforms: {
  28. opacity: { value: 0.5 },
  29. u_alphatest: { value: 1 },
  30. map: { value: undefined }
  31. },
  32. vertexShader: shaders.mesh.vs,
  33. fragmentShader: shaders.mesh.fs,
  34. transparent: true,
  35. side: THREE.DoubleSide
  36. })
  37. constructor(model: IModel) {
  38. super()
  39. this.name = model.name
  40. this.material = Model.shaderMaterial.clone()
  41. this.positionV = new THREE.Vector3().copy(model.transform.translation);
  42. this.showProgress = 0
  43. this.hideProgress = 0
  44. this.fade = 1
  45. this.visibility = true
  46. this.frustumCulled = false
  47. }
  48. // public setVisible( visibility:boolean ) {
  49. // this.visibility = visibility;
  50. // }
  51. // public update( camera: THREE.Camera ) {
  52. // let distance = camera.position.distanceTo( this.positionV );
  53. // this.fade = THREE.Math.clamp( this.fade + (this.visibility ? 0.016 / 2 : -0.016 / 2 ), 0, 1 );
  54. // this.material.uniforms["u_alphatest"].value = this.fade;
  55. // this.visible = (distance < 30 && this.fade != 0);
  56. // }
  57. }
  58. /**
  59. * 模型组件
  60. */
  61. export class Component extends ComponentBase {
  62. private models: Map<string, Model> = new Map<string, Model>();
  63. private static bufferGeometry = new THREE.BufferGeometry()
  64. private static texture = new THREE.Texture()
  65. get list() {
  66. return Array.from(this.models.values())
  67. }
  68. add(model: IModel) {
  69. if (!model.name) {
  70. throw new Error('title.name is require')
  71. }
  72. this.models.set(model.name, new Model(model))
  73. }
  74. get(name: string): Model {
  75. return this.models.get(name)
  76. }
  77. setObj(file: IFile) {
  78. const model = this.get(file.name)
  79. const geometry = Component.bufferGeometry.clone()
  80. geometry.addAttribute('normal', new THREE.BufferAttribute(new Float32Array(file.normal), 3, false))
  81. geometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array(file.position), 3, false))
  82. geometry.addAttribute('uv', new THREE.BufferAttribute(new Float32Array(file.uv), 2, false))
  83. model.geometry = geometry
  84. this.root.get<ScenesSystem>(ScenesSystem.name).scene.add(model)
  85. }
  86. setTexture(file: IFile) {
  87. const material = this.get(file.name).material
  88. const texture = Component.texture.clone()
  89. const blob = new Blob([file.buffer]);
  90. const data = URL.createObjectURL(blob)
  91. const img = new Image();
  92. img.src = data;
  93. img.onload = () => {
  94. texture.image = img
  95. texture.format = THREE.RGBFormat;
  96. texture.needsUpdate = true;
  97. material.uniforms.map.value = texture;
  98. material.needsUpdate = true
  99. }
  100. }
  101. }
  102. /**
  103. * 模型组件实例
  104. */
  105. export const ModelComponent = new Component()