@@ -13,17 +13,25 @@ public struct RawTexture: Sendable {
1313 self . imageSize = imageSize
1414 self . imageData = imageData
1515 }
16+
17+ public init ( imageSize: Size2i ) {
18+ self . imageSize = imageSize
19+ self . imageData = Data ( repeating: 0 , count: imageSize. width * imageSize. height * 4 )
20+ for alphaIndex in stride ( from: 3 , to: self . imageData. count, by: 4 ) {
21+ self . imageData [ alphaIndex] = . max
22+ }
23+ }
1624}
1725
1826public extension RawTexture {
1927 @inlinable
2028 nonmutating func color( at pixelCoordinate: Position2i ) -> Color {
21- return self [ index ( at : pixelCoordinate) ]
29+ return self [ index ( for : pixelCoordinate) ]
2230 }
2331
2432 @inlinable
2533 mutating func setColor( _ color: Color , at pixelCoordinate: Position2i ) {
26- self [ index ( at : pixelCoordinate) ] = color
34+ self [ index ( for : pixelCoordinate) ] = color
2735 }
2836
2937 @inlinable
@@ -38,38 +46,74 @@ public extension RawTexture {
3846}
3947
4048public extension RawTexture {
49+ @inlinable
50+ nonmutating func color( at textureCoordinate: Position2f ) -> Color {
51+ let pixelCoord = self . pixelCoordinate ( for: textureCoordinate)
52+ return self . color ( at: pixelCoord)
53+ }
54+
55+ @inlinable
56+ mutating func setColor( _ color: Color , at textureCoordinate: Position2f ) {
57+ let pixelCoord = self . pixelCoordinate ( for: textureCoordinate)
58+ self . setColor ( color, at: pixelCoord)
59+ }
60+
61+ @inlinable
62+ subscript( textureCoordinate: Position2f ) -> Color {
63+ nonmutating get {
64+ return self . color ( at: textureCoordinate)
65+ }
66+ mutating set {
67+ self . setColor ( newValue, at: textureCoordinate)
68+ }
69+ }
70+ }
71+
72+ public extension RawTexture {
73+ func isAlphaChannelSubMax( at index: Int ) -> Bool {
74+ return imageData [ ( index * 4 ) + 3 ] < . max
75+ }
76+ }
77+
78+ public extension RawTexture {
79+ /// The UV space size of a single pixel
80+ @inlinable
81+ var pixelSize : Size2f {
82+ return Size2f . one / Size2f( self . imageSize)
83+ }
4184 /// The UV position for the pixel
4285 @inlinable
43- func textureCoordinate( at pixelCoordinate: Position2i ) -> Position2f {
44- return Position2f (
45- x: Float ( pixelCoordinate. x) / Float( imageSize. width) ,
46- y: Float ( pixelCoordinate. y) / Float( imageSize. height)
47- )
86+ func textureCoordinate( for pixelCoordinate: Position2i ) -> Position2f {
87+ let pixelSize = self . pixelSize
88+ return ( Position2f ( pixelCoordinate) * pixelSize) + ( pixelSize / 2 )
4889 }
4990
5091 @inlinable
51- func textureCoordinate( at index: Index ) -> Position2f {
52- return self . textureCoordinate ( at : self . pixelCoordinate ( at : index) )
92+ func textureCoordinate( for index: Index ) -> Position2f {
93+ return self . textureCoordinate ( for : self . pixelCoordinate ( for : index) )
5394 }
5495
5596 @inlinable
56- func pixelCoordinate( at textureCoordinate: Position2f ) -> Position2i {
57- return Position2i (
58- x: Int ( Float ( imageSize. width) * textureCoordinate. x) ,
59- y: Int ( Float ( imageSize. height) * textureCoordinate. y)
60- )
97+ func index( for textureCoordinate: Position2f ) -> Index {
98+ return self . index ( for: self . pixelCoordinate ( for: textureCoordinate) )
99+ }
100+
101+ @inlinable
102+ func pixelCoordinate( for textureCoordinate: Position2f ) -> Position2i {
103+ let pixelSize = self . pixelSize
104+ return Position2i ( textureCoordinate / pixelSize)
61105 }
62106
63107 @inlinable
64- func pixelCoordinate( at index: Index ) -> Position2i {
108+ func pixelCoordinate( for index: Index ) -> Position2i {
65109 return Position2i (
66110 x: index % self . imageSize. width,
67111 y: index / self . imageSize. width
68112 )
69113 }
70114
71115 @inlinable
72- func index( at pixelCoordinate: Position2i ) -> Index {
116+ func index( for pixelCoordinate: Position2i ) -> Index {
73117 return ( ( self . imageSize. width * pixelCoordinate. y) + pixelCoordinate. x)
74118 }
75119}
0 commit comments