Line data Source code
1 0 : /*
2 :
3 : OOProbabilisticTextureManager.m
4 :
5 :
6 : Copyright (C) 2007-2013 Jens Ayton
7 :
8 : Permission is hereby granted, free of charge, to any person obtaining a copy
9 : of this software and associated documentation files (the "Software"), to deal
10 : in the Software without restriction, including without limitation the rights
11 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 : copies of the Software, and to permit persons to whom the Software is
13 : furnished to do so, subject to the following conditions:
14 :
15 : The above copyright notice and this permission notice shall be included in all
16 : copies or substantial portions of the Software.
17 :
18 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 : SOFTWARE.
25 :
26 : */
27 :
28 : #import "OOProbabilisticTextureManager.h"
29 : #import "ResourceManager.h"
30 : #import "OOTexture.h"
31 : #import "OOCollectionExtractors.h"
32 : #import "PlayerEntityScriptMethods.h"
33 :
34 :
35 : @implementation OOProbabilisticTextureManager
36 :
37 : - (id)initWithPListName:(NSString *)plistName
38 : options:(uint32_t)options
39 : anisotropy:(GLfloat)anisotropy
40 : lodBias:(GLfloat)lodBias
41 : {
42 : return [self initWithPListName:plistName
43 : options:options
44 : anisotropy:anisotropy
45 : lodBias:lodBias
46 : seed:RANROTGetFullSeed()];
47 : }
48 :
49 :
50 : - (id)initWithPListName:(NSString *)plistName
51 : options:(uint32_t)options
52 : anisotropy:(GLfloat)anisotropy
53 : lodBias:(GLfloat)lodBias
54 : seed:(RANROTSeed)seed
55 : {
56 : BOOL OK = YES;
57 : NSArray *config = nil;
58 : NSUInteger i, count, j;
59 : id entry = nil;
60 : NSString *name = nil;
61 : float probability;
62 : OOTexture *texture = nil;
63 : int galID = -1;
64 : id object = nil;
65 :
66 : self = [super init];
67 : if (self == nil) OK = NO;
68 :
69 : if (OK)
70 : {
71 : config = [ResourceManager arrayFromFilesNamed:plistName inFolder:@"Config" andMerge:YES];
72 : if (config == nil) OK = NO;
73 : }
74 :
75 : if (OK)
76 : {
77 : count = [config count];
78 :
79 : _textures = malloc(sizeof *_textures * count);
80 : _prob = malloc(sizeof *_prob * count);
81 : _galaxy = malloc(sizeof *_galaxy * count);
82 : _probMaxGal = malloc(sizeof *_probMaxGal * (kOOMaximumGalaxyID + 1));
83 :
84 : if (_textures == NULL || _prob == NULL || _galaxy == NULL) OK = NO;
85 : }
86 :
87 : if (OK)
88 : {
89 : for (i = 0; i <= kOOMaximumGalaxyID; i++) _probMaxGal[i] = 0;
90 :
91 : // Go through list and load textures.
92 : for (i = 0; i != count; ++i)
93 : {
94 : entry = [config objectAtIndex:i];
95 : galID = -1;
96 : if ([entry isKindOfClass:[NSDictionary class]])
97 : {
98 : name = [(NSDictionary *)entry oo_stringForKey:@"texture"];
99 : probability = [entry oo_floatForKey:@"probability" defaultValue:1.0f];
100 : object = [entry objectForKey:@"galaxy"];
101 : if ([object isKindOfClass:[NSString class]])
102 : {
103 : galID = [object intValue];
104 : }
105 : else if (object != nil)
106 : {
107 : OOLog(@"textures.load", @"***** ERROR: %@ for texture %@ is not a string.", @"galaxy", name);
108 : }
109 : }
110 : else if ([entry isKindOfClass:[NSString class]])
111 : {
112 : name = entry;
113 : probability = 1.0f;
114 : }
115 : else
116 : {
117 : name = nil;
118 : }
119 :
120 : if (name != nil && 0.0f < probability)
121 : {
122 : texture = [OOTexture textureWithName:name
123 : inFolder:@"Textures"
124 : options:options
125 : anisotropy:anisotropy
126 : lodBias:lodBias];
127 : if (texture != nil)
128 : {
129 : _textures[_count] = [texture retain];
130 : _prob[_count] = probability + (galID >= 0 ? _probMaxGal[galID] : _probMax);
131 : _galaxy[_count] = (galID >= 0 ? galID : -1);
132 : if (galID >= 0) {
133 : _probMaxGal[galID] += probability;
134 : }
135 : else
136 : {
137 : for (j = 0; j <= kOOMaximumGalaxyID; j++) _probMaxGal[j] += probability;
138 : _probMax += probability;
139 : }
140 : ++_count;
141 : }
142 : }
143 : }
144 :
145 : if (_count == 0) OK = NO;
146 : }
147 :
148 : if (OK) _seed = seed;
149 :
150 : if (!OK)
151 : {
152 : [self release];
153 : self = nil;
154 : }
155 :
156 : return self;
157 : }
158 :
159 :
160 0 : - (void)dealloc
161 : {
162 : unsigned i;
163 :
164 : if (_textures != NULL)
165 : {
166 : for (i = 0; i != _count; ++i)
167 : {
168 : [_textures[i] release];
169 : }
170 : free(_textures);
171 : }
172 :
173 : if (_prob != NULL) free(_prob);
174 : if (_galaxy != NULL) free(_galaxy);
175 : if (_probMaxGal != NULL) free(_probMaxGal);
176 :
177 : [super dealloc];
178 : }
179 :
180 :
181 0 : - (NSString *)description
182 : {
183 : return [NSString stringWithFormat:@"<%@ %p>{%u textures, cumulative probability=%g}", [self class], self, _count, _probMax];
184 : }
185 :
186 :
187 : - (OOTexture *)selectTexture
188 : {
189 : float selection;
190 : unsigned i;
191 : int hold = -1;
192 : int galID = (int)[PLAYER currentGalaxyID];
193 :
194 : selection = randfWithSeed(&_seed);
195 :
196 : selection *= _probMaxGal[galID];
197 :
198 : for (i = 0; i != _count; ++i)
199 : {
200 : if (_galaxy[i] == -1 || _galaxy[i] == galID)
201 : {
202 : // make a note of the index of the first texture that meets the galaxy list criteria (but only if _galaxy is set)
203 : if (hold == -1 && _prob[i] > 0 && _galaxy[i] == galID) hold = i;
204 : if (selection <= _prob[i]) return _textures[i];
205 : }
206 : }
207 :
208 : // first catch point if loop above fails to return a texture
209 : // return first texture that meets the galaxy list criteria and has a probability > 0
210 : if (hold >= 0)
211 : {
212 : OOLog(@"probabilisticTextureManager.internalWarning", @"%s: overrun! Galaxy List requirements not met. Choosing first texture available for galaxy.", __PRETTY_FUNCTION__);
213 : return _textures[hold];
214 : }
215 :
216 : OOLog(@"probabilisticTextureManager.internalFailure", @"%s: overrun! Choosing last texture.", __PRETTY_FUNCTION__);
217 : return _textures[_count - 1];
218 : }
219 :
220 :
221 : - (unsigned)textureCount
222 : {
223 : return _count;
224 : }
225 :
226 :
227 : - (void)ensureTexturesLoaded
228 : {
229 : unsigned i;
230 :
231 : for (i = 0; i != _count; ++i)
232 : {
233 : [_textures[i] ensureFinishedLoading];
234 : }
235 : }
236 :
237 :
238 : - (RANROTSeed)seed
239 : {
240 : return _seed;
241 : }
242 :
243 :
244 : - (void)setSeed:(RANROTSeed)seed
245 : {
246 : _seed = seed;
247 : }
248 :
249 : @end
|