Oolite 1.91.0.7646-241128-10e222e
Loading...
Searching...
No Matches
OOConvertCubeMapToLatLong.m
Go to the documentation of this file.
1/*
2
3OOConvertCubeMapToLatLong.m
4
5Convert a cube map texture to a lat/long texture.
6
7
8Copyright (C) 2010-2013 Jens Ayton
9
10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files (the "Software"), to deal
12in the Software without restriction, including without limitation the rights
13to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14copies of the Software, and to permit persons to whom the Software is
15furnished to do so, subject to the following conditions:
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26SOFTWARE.
27
28*/
29
31#import "OOTextureScaling.h"
32
33
34#define kPiF (3.14159265358979323846264338327950288f)
35
36
37OOPixMap OOConvertCubeMapToLatLong(OOPixMap sourcePixMap, OOPixMapDimension height, BOOL leaveSpaceForMipMaps)
38{
39 if (!OOIsValidPixMap(sourcePixMap) || sourcePixMap.format != kOOPixMapRGBA || sourcePixMap.height != sourcePixMap.width * 6)
40 {
41 return kOONullPixMap;
42 }
43
44 NSCParameterAssert(height > 0);
45
46 height *= 2;
47 OOPixMapDimension width = height * 2;
48 OOPixMap outPixMap = OOAllocatePixMap(width, height, 4, 0, 0);
49 if (!OOIsValidPixMap(outPixMap)) return kOONullPixMap;
50
52 uint32_t *pixel = outPixMap.pixels;
53 float fheight = height;
54 float rheight = 1.0f / fheight;
55
56 float halfSize = (sourcePixMap.width - 1) * 0.5f;
57 uint8_t *srcBytes = sourcePixMap.pixels;
58
59 // Build tables of sin/cos of longitude.
60 float sinTable[width];
61 float cosTable[width];
62 for (x = 0; x < width; x++)
63 {
64 float lon = ((float)x * rheight) * kPiF;
65 sinTable[x] = sin(lon);
66 cosTable[x] = cos(lon);
67 }
68
69 for (y = 0; y < height; y++)
70 {
71 // Calcuate sin/cos of latitude.
72 /*
73 Clang static analyzer (Xcode 3.2.5 version, through to Xcode 4.4
74 and freestanding checker-268 at least) says:
75 "Assigned value is garbage or undefined."
76 Memsetting sinTable to all-zeros moves this to the cosTable line.
77 Since every value in each of those tables is in fact defined, this
78 is an error in the analyzer.
79 -- Ahruman 2011-01-25/2012-09-14
80 */
81 float cy = -sinTable[width * 3 / 4 - y];
82 float lac = -cosTable[width * 3 / 4 - y];
83 float ay = fabs(cy);
84
85 for (x = 0; x < width; x++)
86 {
87 float cx = sinTable[x] * lac;
88 float cz = cosTable[x] * lac;
89
90 float ax = fabs(cx);
91 float az = fabs(cz);
92
93 // Y offset of start of this face in image.
94 OOPixMapDimension yOffset;
95
96 // Coordinates within selected face.
97 float x, y, r;
98
99 // Select source face.
100 if (ax >= ay && ax >= az)
101 {
102 x = cz;
103 y = -cy;
104 r = ax;
105 if (0.0f < cx)
106 {
107 yOffset = 0;
108 }
109 else
110 {
111 x = -x;
112 yOffset = 1;
113 }
114 }
115 else if (ay >= ax && ay >= az)
116 {
117 x = cx;
118 y = cz;
119 r = ay;
120 if (0.0f < cy)
121 {
122 y = -y;
123 yOffset = 2;
124 }
125 else
126 {
127 yOffset = 3;
128 }
129 }
130 else
131 {
132 x = cx;
133 y = -cy;
134 r = az;
135 if (0.0f < cz)
136 {
137 x = -x;
138 yOffset = 5;
139 }
140 else
141 {
142 yOffset = 4;
143 }
144 }
145
146 // Scale coordinates.
147 r = 1.0f / r;
148 OOPixMapDimension ix = (x * r + 1.0f) * halfSize;
149 OOPixMapDimension iy = (y * r + 1.0f) * halfSize;
150
151#ifndef NDEBUG
152 assert(ix < sourcePixMap.width && iy < sourcePixMap.width);
153#endif
154
155 // Look up pixel.
156 iy += sourcePixMap.width * yOffset;
157
158 uint32_t *row = (uint32_t *)(srcBytes + iy * sourcePixMap.rowBytes);
159 *pixel++ = row[ix];
160 }
161 }
162
163 // Scale to half size for supersamplingness.
164 return OOScalePixMap(outPixMap, width / 2, height / 2, leaveSpaceForMipMaps);
165}
OOPixMap OOConvertCubeMapToLatLong(OOPixMap sourcePixMap, OOPixMapDimension height, BOOL leaveSpaceForMipMaps)
#define kPiF
uint_fast32_t OOPixMapDimension
Definition OOPixMap.h:33
@ kOOPixMapRGBA
Definition OOPixMap.h:43
const OOPixMap kOONullPixMap
Definition OOPixMap.m:31
OOPixMap OOAllocatePixMap(OOPixMapDimension width, OOPixMapDimension height, OOPixMapFormat format, size_t rowBytes, size_t bufferSize)
Definition OOPixMap.m:73
BOOL OOIsValidPixMap(OOPixMap pixMap)
Definition OOPixMap.m:42
float y
float x
OOPixMap OOScalePixMap(OOPixMap srcPixMap, OOPixMapDimension dstWidth, OOPixMapDimension dstHeight, BOOL leaveSpaceForMipMaps)
OOPixMapDimension height
Definition OOPixMap.h:50
size_t rowBytes
Definition OOPixMap.h:52
void * pixels
Definition OOPixMap.h:49
OOPixMapDimension width
Definition OOPixMap.h:50
OOPixMapFormat format
Definition OOPixMap.h:51