|
7 | 7 |
|
8 | 8 | import CAssimp
|
9 | 9 |
|
| 10 | +/// Helper structure to describe an embedded texture |
| 11 | +/// |
| 12 | +/// Normally textures are contained in external files but some file formats embed them directly in the model file. |
| 13 | +/// There are two types of embedded textures: |
| 14 | +/// 1. Uncompressed textures. |
| 15 | +/// The color data is given in an uncompressed format. |
| 16 | +/// 2. Compressed textures stored in a file format like png or jpg. |
| 17 | +/// The raw file bytes are given so the application must utilize an image decoder (e.g. DevIL) to get access to the actual color data. |
| 18 | +/// |
| 19 | +/// Embedded textures are referenced from materials using strings like "*0", "*1", etc. as the texture paths (a single asterisk character followed by the zero-based index of the texture in the aiScene::mTextures array). |
10 | 20 | public struct AiTexture {
|
11 | 21 | let texture: aiTexture
|
12 | 22 |
|
13 | 23 | public init(_ aiTexture: aiTexture) {
|
14 | 24 | texture = aiTexture
|
15 | 25 | }
|
16 | 26 |
|
17 |
| - var width: Int { |
| 27 | + /// Texture original filename. |
| 28 | + /// |
| 29 | + /// Used to get the texture reference. |
| 30 | + public var filename: String? { |
| 31 | + String(aiString: texture.mFilename) |
| 32 | + } |
| 33 | + |
| 34 | + /// A hint from the loader to make it easier for applications |
| 35 | + /// to determine the type of embedded textures. |
| 36 | + /// |
| 37 | + /// If mHeight != 0 this member is show how data is packed. Hint will consist of |
| 38 | + /// two parts: channel order and channel bitness (count of the bits for every |
| 39 | + /// color channel). For simple parsing by the viewer it's better to not omit |
| 40 | + /// absent color channel and just use 0 for bitness. For example: |
| 41 | + /// 1. Image contain RGBA and 8 bit per channel, achFormatHint == "rgba8888"; |
| 42 | + /// 2. Image contain ARGB and 8 bit per channel, achFormatHint == "argb8888"; |
| 43 | + /// 3. Image contain RGB and 5 bit for R and B channels and 6 bit for G channel, achFormatHint == "rgba5650"; |
| 44 | + /// 4. One color image with B channel and 1 bit for it, achFormatHint == "rgba0010"; |
| 45 | + /// If mHeight == 0 then achFormatHint is set set to '\\0\\0\\0\\0' if the loader has no additional |
| 46 | + /// information about the texture file format used OR the |
| 47 | + /// file extension of the format without a trailing dot. If there |
| 48 | + /// are multiple file extensions for a format, the shortest |
| 49 | + /// extension is chosen (JPEG maps to 'jpg', not to 'jpeg'). |
| 50 | + /// E.g. 'dds\\0', 'pcx\\0', 'jpg\\0'. All characters are lower-case. |
| 51 | + /// The fourth character will always be '\\0'. |
| 52 | + public var achFormatHint: String { |
| 53 | + CArray<CChar>.read(texture.achFormatHint) { body in |
| 54 | + String(cString: body.baseAddress!) |
| 55 | + } |
| 56 | + } |
| 57 | + |
| 58 | + /// Width of the texture, in pixels |
| 59 | + /// |
| 60 | + /// If mHeight is zero the texture is compressed in a format like JPEG. |
| 61 | + /// In this case mWidth specifies the size of the memory area pcData is pointing to, in bytes. |
| 62 | + public var width: Int { |
18 | 63 | Int(texture.mWidth)
|
19 | 64 | }
|
20 | 65 |
|
21 |
| - var height: Int { |
| 66 | + /// Height of the texture, in pixels |
| 67 | + /// |
| 68 | + /// If this value is zero, pcData points to a compressed texture in any format (e.g. JPEG). |
| 69 | + public var height: Int { |
22 | 70 | Int(texture.mHeight)
|
23 | 71 | }
|
24 | 72 |
|
25 |
| - var pcData: [aiTexel] { |
26 |
| - [aiTexel](UnsafeMutableBufferPointer<aiTexel>(start: texture.pcData, |
27 |
| - count: width * height)) |
| 73 | + @inline(__always) |
| 74 | + public var isCompressed: Bool { |
| 75 | + height == 0 |
| 76 | + } |
| 77 | + |
| 78 | + /// Data of the texture. |
| 79 | + /// |
| 80 | + /// Points to an array of mWidth * mHeight aiTexel's. |
| 81 | + /// The format of the texture data is always ARGB8888 to make the implementation for user of the library as easy as possible. |
| 82 | + /// If mHeight = 0 this is a pointer to a memory buffer of size mWidth containing the compressed texture data. |
| 83 | + public var pcData: [aiTexel] { |
| 84 | + let count: Int = height == 0 ? width : (width * height) |
| 85 | + return [aiTexel](UnsafeMutableBufferPointer<aiTexel>(start: texture.pcData, |
| 86 | + count: count)) |
| 87 | + } |
| 88 | + |
| 89 | + public var rawPcData: UnsafeBufferPointer<UInt8> { |
| 90 | + let count: Int = height == 0 ? width : (width * height) |
| 91 | + let length = MemoryLayout<aiTexel>.stride * count |
| 92 | + return texture.pcData.withMemoryRebound(to: UInt8.self, capacity: length) { ptr in |
| 93 | + UnsafeBufferPointer<UInt8>(start: ptr, count: length) |
| 94 | + } |
28 | 95 | }
|
29 | 96 | }
|
30 | 97 |
|
|
0 commit comments