universo-platform-3d

Форк
0
111 строк · 3.3 Кб
1
import { BadRequestException, Inject, Injectable, Logger } from '@nestjs/common'
2
import { pipeline, PassThrough } from 'stream'
3
import { parser } from 'stream-json'
4
import { pick } from 'stream-json/filters/Pick'
5
import StreamValues, { streamValues } from 'stream-json/streamers/StreamValues'
6
import FilterBase from 'stream-json/filters/FilterBase'
7
import { Document, Extension, NodeIO } from '@gltf-transform/core'
8
import { MirrorEquipableExtension } from './glb-extensions/mirror-equipable.extension'
9
import { GLBAnalyzingHandler } from './abstractions/glb-analyzing-handler.type'
10
import { FILE_ANALYZING_MIMETYPES } from './enums/file-analyzing-mimetypes.enum'
11
import { ALL_EXTENSIONS } from '@gltf-transform/extensions'
12

13
@Injectable()
14
export class AssetAnalyzingService {
15
  constructor(
16
    private readonly logger: Logger,
17
    @Inject('NODE_IO') private readonly nodeIo: NodeIO
18
  ) {}
19

20
  public async isAssetEquipable(
21
    assetFile: Express.Multer.File
22
  ): Promise<boolean> {
23
    switch (assetFile.mimetype) {
24
      case FILE_ANALYZING_MIMETYPES.GLB:
25
        return await this.isGLBAssetEquippable(assetFile)
26
      case FILE_ANALYZING_MIMETYPES.GLTF:
27
        return await this.isGLTFAssetEquippable(assetFile)
28
      default:
29
        return false
30
    }
31
  }
32

33
  private async isGLBAssetEquippable(
34
    glbAssetFile: Express.Multer.File
35
  ): Promise<boolean> {
36
    return await this.getGLBAnalyzingPipeline(
37
      glbAssetFile,
38
      (glbDocument: Document) =>
39
        glbDocument
40
          .getRoot()
41
          .listExtensionsUsed()
42
          .some(
43
            (asset) =>
44
              asset.extensionName === MirrorEquipableExtension.EXTENSION_NAME
45
          ),
46
      [MirrorEquipableExtension, ...ALL_EXTENSIONS]
47
    )
48
  }
49

50
  private async isGLTFAssetEquippable(
51
    gltfAssetFile: Express.Multer.File
52
  ): Promise<boolean> {
53
    try {
54
      return await new Promise((resolve, reject) => {
55
        this.getGLTFAnalyzingPipeline(gltfAssetFile, {
56
          filter: 'extensions'
57
        })
58
          .on('data', ({ value }) => {
59
            if (value.MIRROR_equipable) {
60
              resolve(true)
61
            }
62
          })
63
          .on('error', (err) => reject(err))
64
          .on('end', () => {
65
            resolve(false)
66
          })
67
      })
68
    } catch (err) {
69
      throw new BadRequestException('Invalid GLTF file')
70
    }
71
  }
72

73
  private getGLTFAnalyzingPipeline(
74
    gltfAssetFile: Express.Multer.File,
75
    filter: FilterBase.FilterOptions
76
  ): StreamValues {
77
    const bufferStream = new PassThrough()
78
    bufferStream.end(gltfAssetFile.buffer)
79

80
    return pipeline(
81
      bufferStream,
82
      parser(),
83
      pick(filter),
84
      streamValues(),
85
      (err: Error) => {
86
        if (err) {
87
          this.logger.error('GLTF Processing Pipeline failed.', err.stack)
88
        } else {
89
          this.logger.log('GLTF Processing Pipeline completed.')
90
        }
91
      }
92
    )
93
  }
94

95
  private async getGLBAnalyzingPipeline(
96
    glbAssetFile: Express.Multer.File,
97
    processingHandler: GLBAnalyzingHandler,
98
    extensions: (typeof Extension)[] = []
99
  ): Promise<boolean> {
100
    try {
101
      const glbDocument = await this.nodeIo
102
        .registerExtensions(extensions)
103
        .readBinary(glbAssetFile.buffer)
104

105
      return await processingHandler(glbDocument)
106
    } catch (err) {
107
      this.logger.error('GLB Processing Pipeline failed.', err.stack)
108
      throw new BadRequestException('Invalid GLB file')
109
    }
110
  }
111
}
112

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.