26 |
#include <Foundation/NSString.h> |
#include <Foundation/NSString.h> |
27 |
#include <Foundation/NSValue.h> |
#include <Foundation/NSValue.h> |
28 |
#include <Foundation/NSData.h> |
#include <Foundation/NSData.h> |
29 |
|
#include <Foundation/NSFileManager.h> |
30 |
|
#include <Foundation/NSKeyValueCoding.h> |
31 |
|
#include <Foundation/NSException.h> |
32 |
|
|
33 |
#include <GL/glut.h> |
#include <GL/glut.h> |
34 |
#include <math.h> |
#include <math.h> |
45 |
|
|
46 |
|
|
47 |
@interface MdlModel (Private) |
@interface MdlModel (Private) |
48 |
- (void) _loadModel: (NSString *)fileMdl; |
- (void) _setModel: (NSString *)modelPath; |
49 |
- (void) _loadAnimations: (NSString *)fileCfg; |
- (void) _setAnimations: (NSDictionary *)propertyList; |
50 |
|
- (void) _setTextures: (NSArray *)textures; |
51 |
- (unsigned) _mesh : (NSString *)name; |
- (unsigned) _mesh : (NSString *)name; |
52 |
- (GLuint) _texture: (int32_t)noMesh; |
- (GLuint) _texture: (int32_t)noMesh; |
|
- (void) _loadTexturesWithSkin: (NSString *)texName; |
|
53 |
- (void) _calcModelNbElements; |
- (void) _calcModelNbElements; |
54 |
- (void) _calcModelNbVertice; |
- (void) _calcModelNbVertice; |
55 |
- (void) _calcModelVerticeIndices; |
- (void) _calcModelVerticeIndices; |
64 |
@implementation MdlModel |
@implementation MdlModel |
65 |
|
|
66 |
/** |
/** |
67 |
* This method builds an instance of MdlModel. |
* Allocates and initializes a model using the content of the propert |
68 |
* The parameter gives us files names to load model data, the model name MD3, |
* list. The model is also autoreleased. |
69 |
* the config file name. The texture name is a SKIN file. It may exist, |
*/ |
70 |
* otherwise textures are read in MD3 file. |
+ (id) modelWithPropertyList: (NSDictionary *)propertyList |
|
*/ |
|
|
- (id) initWithName: (NSString *)modelName |
|
|
withTexName: (NSString *)texName |
|
|
withConfigName: (NSString *)cfgName |
|
71 |
{ |
{ |
72 |
NSParameterAssert (modelName); |
NSParameterAssert (propertyList); |
73 |
NSParameterAssert ([modelName length] != 0); |
|
74 |
|
return AUTORELEASE([[self alloc] initWithPropertyList: propertyList]); |
75 |
|
} |
76 |
|
|
77 |
NSParameterAssert (cfgName); |
/** |
78 |
NSParameterAssert ([cfgName length] != 0); |
* Allocates and initializes a model using the content of the file. |
79 |
|
* The file must contain a valid property list. |
80 |
|
* The model is also autoreleased. |
81 |
|
*/ |
82 |
|
+ (id) modelWithContentsOfFile: (NSString *)path |
83 |
|
{ |
84 |
|
NSParameterAssert (path); |
85 |
|
NSParameterAssert ([path length] != 0); |
86 |
|
|
87 |
|
return AUTORELEASE([[self alloc] initWithContentsOfFile: path]); |
88 |
|
} |
89 |
|
|
90 |
|
/** |
91 |
|
* Initializes the model with the content of the property list. |
92 |
|
*/ |
93 |
|
- (id) initWithPropertyList: (NSDictionary *)propertyList |
94 |
|
{ |
95 |
|
NSParameterAssert (propertyList); |
96 |
|
|
97 |
self = [super init]; |
self = [super init]; |
|
|
|
98 |
if (self != nil) |
if (self != nil) |
99 |
{ |
{ |
100 |
[self _loadModel: modelName]; |
[self takeValuesFromDictionary: propertyList]; |
101 |
[self _loadAnimations: cfgName]; |
} |
102 |
|
|
103 |
|
return self; |
104 |
|
} |
105 |
|
|
106 |
[self _loadTexturesWithSkin: texName]; |
/** |
107 |
} |
* Initializes the model with the contents of the file. |
108 |
|
* The file must contain a valid property list. |
109 |
|
*/ |
110 |
|
- (id) initWithContentsOfFile: (NSString *)path |
111 |
|
{ |
112 |
|
NSParameterAssert (path); |
113 |
|
NSParameterAssert ([path length] != 0); |
114 |
|
|
115 |
|
NSDictionary *propertyList |
116 |
|
= [NSDictionary dictionaryWithContentsOfFile: path]; |
117 |
|
|
118 |
|
/* We change the current path */ |
119 |
|
NSFileManager *fileManager = [NSFileManager defaultManager]; |
120 |
|
NSString *currentDir = [fileManager currentDirectoryPath]; |
121 |
|
[fileManager changeCurrentDirectoryPath: |
122 |
|
[path stringByDeletingLastPathComponent]]; |
123 |
|
|
124 |
|
self = [self initWithPropertyList: propertyList]; |
125 |
|
|
126 |
|
/* We restore the old path */ |
127 |
|
[fileManager changeCurrentDirectoryPath: currentDir]; |
128 |
|
|
129 |
return self; |
return self; |
130 |
} |
} |
131 |
|
|
|
|
|
132 |
- (void) dealloc |
- (void) dealloc |
133 |
{ |
{ |
134 |
free(_verticeIndices); |
free(_verticeIndices); |
149 |
|
|
150 |
|
|
151 |
/** |
/** |
152 |
* This method loads data for the model. |
* Loads data from the md3 model. |
153 |
*/ |
*/ |
154 |
- (void) _loadModel: (NSString *)fileMdl |
- (void) _setModel: (NSString *)modelPath |
155 |
{ |
{ |
156 |
NSParameterAssert (fileMdl); |
NSParameterAssert (modelPath); |
157 |
NSParameterAssert ([fileMdl length] != 0); |
NSParameterAssert ([modelPath length] != 0); |
158 |
|
|
159 |
_data = [[MD3Data alloc] initWithFile: fileMdl]; |
_data = [[MD3Data alloc] initWithFile: modelPath]; |
160 |
if (_data == nil) |
NSAssert (_data, @"Could not open md3 file"); |
|
{ |
|
|
fprintf (stderr, "unknown file name %s \n", [fileMdl cString]); |
|
|
abort (); |
|
|
} |
|
161 |
|
|
162 |
[self _calcModelInfomations]; |
[self _calcModelInfomations]; |
163 |
} |
} |
164 |
|
|
165 |
/** |
/** |
166 |
* This method loads the model animations. The file is a ".cfg" file. |
* Loads the model animations from dictionary, where keys |
167 |
|
* are the animation name, and objects MdlAnimation property list. |
168 |
*/ |
*/ |
169 |
- (void) _loadAnimations: (NSString *)fileCfg |
- (void) _setAnimations: (NSDictionary *)propertyList |
170 |
{ |
{ |
171 |
NSParameterAssert (fileCfg); |
NSParameterAssert (propertyList); |
|
NSParameterAssert ([fileCfg length] != 0); |
|
172 |
|
|
|
NSDictionary *animsCfg |
|
|
= [NSDictionary dictionaryWithContentsOfFile: fileCfg]; |
|
|
|
|
173 |
_animations |
_animations |
174 |
= [[NSMutableDictionary alloc] initWithCapacity: [animsCfg count]]; |
= [[NSMutableDictionary alloc] initWithCapacity: [propertyList count]]; |
175 |
|
|
176 |
NSEnumerator *enumerator = [animsCfg keyEnumerator]; |
NSEnumerator *enumerator = [propertyList keyEnumerator]; |
177 |
NSString *name; |
NSString *name; |
178 |
while ( (name = [enumerator nextObject]) ) |
while ( (name = [enumerator nextObject]) ) |
179 |
{ |
{ |
180 |
NSDictionary *animInfos = [animsCfg objectForKey: name]; |
MdlAnimation *anim = [MdlAnimation animWithPropertyList: |
181 |
|
[propertyList objectForKey: name]]; |
182 |
MdlAnimation *anim = [MdlAnimation alloc] ; |
|
183 |
anim = [anim initWithAnimationName: name |
[_animations setObject: anim |
|
start: |
|
|
[[animInfos objectForKey: @"start"] intValue] |
|
|
nb: |
|
|
[[animInfos objectForKey: @"nb"] intValue] |
|
|
loop: |
|
|
[[animInfos objectForKey: @"loop"] intValue] |
|
|
frame: |
|
|
[[animInfos objectForKey: @"frame"] intValue]]; |
|
|
|
|
|
[_animations setObject: anim |
|
184 |
forKey: name]; |
forKey: name]; |
185 |
} |
} |
186 |
} |
} |
187 |
|
|
188 |
/** |
/** |
189 |
* This method is used to load textures contained in the MD3Data. |
* Loads the model textures from the array. Each entry of the array contains |
190 |
* The texture name is a SKIN file. It may exist, otherwise textures |
* a texture path whose position correspond to the model mesh number. |
191 |
* are read in MD3 file. |
* If textures is nil, then reads the texture names from the md3 model. |
192 |
*/ |
*/ |
193 |
- (void) _loadTexturesWithSkin: (NSString *)texName |
- (void) _setTextures: (NSArray *)textures |
194 |
{ |
{ |
|
int32_t noMesh; |
|
|
GLuint texture; |
|
|
|
|
195 |
_textures = [[NSMutableArray alloc] initWithCapacity: [_data nbMeshes]]; |
_textures = [[NSMutableArray alloc] initWithCapacity: [_data nbMeshes]]; |
196 |
|
|
197 |
if (texName != nil && ([texName length] != 0)) |
if (textures != nil) |
198 |
{ |
{ |
199 |
NSDictionary *tex; |
int32_t noMesh; |
|
if ( (tex = [NSDictionary dictionaryWithContentsOfFile: texName]) == nil) |
|
|
{ |
|
|
fprintf (stderr, "unknown file name %s \n", [texName cString]); |
|
|
abort (); |
|
|
} |
|
|
|
|
|
NSArray *key = [tex allKeys]; |
|
|
|
|
200 |
for (noMesh = 0; noMesh < [_data nbMeshes]; noMesh++) |
for (noMesh = 0; noMesh < [_data nbMeshes]; noMesh++) |
201 |
{ |
{ |
202 |
texture = |
GLuint texture = |
203 |
[[TextureLoader defaultLoader] |
[[TextureLoader defaultLoader] |
204 |
addTexture: [tex objectForKey: [key objectAtIndex: noMesh]]]; |
addTexture: [textures objectAtIndex: noMesh]]; |
205 |
|
|
206 |
[_textures addObject: [NSNumber numberWithInt: texture]]; |
[_textures addObject: [NSNumber numberWithInt: texture]]; |
207 |
} |
} |
208 |
} |
} |
209 |
else |
else |
210 |
{ |
{ |
211 |
|
int32_t noMesh; |
212 |
for (noMesh = 0; noMesh < [_data nbMeshes]; noMesh++) |
for (noMesh = 0; noMesh < [_data nbMeshes]; noMesh++) |
213 |
{ |
{ |
214 |
NSString *name = [NSString stringWithCString: |
NSString *name = [NSString stringWithCString: |
215 |
[_data meshTexName: noMesh |
[_data meshTexName: noMesh |
216 |
withNumber: 0]]; |
withNumber: 0]]; |
217 |
if([name length] >= 2) |
if ([name length] > 0) |
218 |
{ |
{ |
219 |
texture = [[TextureLoader defaultLoader] addTexture: name]; |
GLuint texture |
220 |
|
= [[TextureLoader defaultLoader] addTexture: name]; |
221 |
[_textures addObject: [NSNumber numberWithInt: texture]]; |
[_textures addObject: [NSNumber numberWithInt: texture]]; |
222 |
} |
} |
223 |
else |
else |
224 |
[_textures addObject: [NSNumber numberWithInt: 0]]; |
{ |
225 |
|
[_textures addObject: [NSNumber numberWithInt: 0]]; |
226 |
|
} |
227 |
} |
} |
228 |
} |
} |
229 |
} |
} |