iPhone SDK Mesh COLLADA importieren
Software: Maya 2008
COLLADA version 1.4
COLLADA Schema unterstützt alle Features, die modern 3D interactive applications brauchen, einschließen Shader Effekten, Animation und Physik Simulation.
Step 1.
Installieren und laden COLLADA plug in für Maya
Step 2.
Wechseln alle Face vom Model zu Dreiecken: Mesh -> Triangulate. (OpenGL ES 1.x do not support QUADE draw).
Step 3.
Export Model mit mayaCollada, dann habe ich a dae(digital asset exchange) file. Eigentlich dea file ist erweitern aus XML File.
Step 4.
Gehen wir zurück zu Xcode und import diesen .dae File into project, öffnen es mit Editor, wir können alle informationen über 3D Model, wie Materialien, Effekte, Geometrie… Ich konzentriere mich auf tag “library geomentry” welche ein Kinder Tag “mesh” hat. Der erste Zeile in diesem Block definiert den Name der Geometrie <geometry id=”pCubeShape1″ name=”pCubeShape1″> dann kommt das wichtige Tag <mesh>, darin gibt es 3 “source” und ein “triangles” Blocks, jede hat ein Array : <float_array id=”pCubeShape1-positions-array” count=”24″> (Position der jede vertex), <float_array id=”pCubeShape1-normals-array” count=”72″>, <source id=”pCubeShape1-map1″ name=”pCubeShape1-map1″> (texture coordinats) and <p> ( bitte sehen Sie Ps). Das ist alles was wir brauchen ein den einfache Mordel zu importieren.
Step 5.
Danach kann ich analysieren das File mit class NSXMLParser vom SDK. In diesem Beispiel male ich Model Figur ohne Texture, deswegen lese ich nur Positions array und die indices array aus <p> aus.
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if(qName) {
elementName = qName;
}
if([elementName isEqualToString:@"accessor"]) {
NSString *accessorAtt = [attributeDict valueForKey:@"source"];
if([accessorAtt isEqualToString:@"#pCubeShape1-positions-array"]) {
NSString *sVertextCount = [attributeDict valueForKey:@"count"];
vertexCount = [sVertextCount intValue];
return;
}
else if([accessorAtt isEqualToString:@"#pCubeShape1-map1-array"]) {
NSString *sMapCount = [attributeDict valueForKey:@"count"];
mapCount = [sMapCount intValue];
return;
}
}
else if([elementName isEqualToString:@"triangles"]) {
NSString *sFaceCount = [attributeDict valueForKey:@"count"];
faceCount = [sFaceCount intValue];
return;
}
else if ([elementName isEqualToString:@"float_array"]) {
NSString *relAtt = [attributeDict valueForKey:@"id"];
if([relAtt isEqualToString:@"pCubeShape1-positions-array"]) {
contentProperty = [NSMutableString string];
array_id = id_positions;
NSLog(@”get positions”);
}
else if([relAtt isEqualToString:@"pCubeShape1-normals-array"]) {
contentProperty = [NSMutableString string];
array_id = id_normals;
NSLog(@”get normals”);
}
else if([relAtt isEqualToString:@"pCubeShape1-map1-array"]) {
contentProperty = [NSMutableString string];
array_id = id_maps;
NSLog(@”get maps”);
}
}
else if ([elementName isEqualToString:@"p"]) {
contentProperty = [NSMutableString string];
NSLog(@”get vertex”);
}
else {
contentProperty = nil;
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (qName) {
elementName = qName;
}
if ([elementName isEqualToString:@"float_array"]) {
if(array_id == id_positions) {
msd.sPosition = contentProperty;
NSLog(@”set postion”);
array_id = -1;
}
if(array_id == id_normals) {
msd.sNormal = contentProperty;
NSLog(@”set normals”);
array_id = -1;
}
if(array_id == id_maps) {
msd.sMap = contentProperty;
NSLog(@”set maps”);
array_id = -1;
}
}
else if ([elementName isEqualToString:@"p"]) {
msd.sIndices = contentProperty;
NSLog(@”set vertex”);
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (contentProperty) {
[contentProperty appendString:string];
}
}
Step 6.
Zum Schluss malen wir Model mit OpenGL ES.
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, mVertices);
glDrawArrays(GL_TRIANGLES, 0, faceCount*3);
glDisableClientState(GL_VERTEX_ARRAY);
Ps:
<p> beinhaltet Indices, die die Vertexattribute einer Anzahl von Dreiecken beschreiben. Die Indices in einem <p>-Element beziehen sich auf verschiedene Eingaben abhaengig von ihrer Ordnung. Der erste Index in einem <p>-Element bezieht sich auf alle Eingaben mit dem Offset 0. Der zweite Index bezieht sich auf alle Eingaben mit dem Offset 1.
Jede Vertex/Ecke der Dreiecke wird …. Nachdem jede Eingabe benutzt wurde, bezieht sich der naechste Index wieder auf die Eingabe mit Offset 0 und beginnt eine neue Vertex/Ecke.
Die Windungsreihenfolge der produzierten Vertices/Ecken ist entgegen dem Uhrzeigersinn und beschreibt die Vorderseite des jeweiligen Dreiecks.
Wenn die primitives ohne Eckennormalen zusammengestellt sind, dann kann die Anwendung per-primitive …. generieren……
Hier ist ein Beispiel eines <triangle>-Elements dass zwei Dreiecke beschreibt. Es gibt zwei <source>-Elemente, die die Position und die Normalen-Daten enthalten, entsprechend den <input>-Element Bedeutungen. Die <p>-Element Indexwerte geben die Reihenfolge in der die Eingabewerte genutzt werden an:
<mesh>
<source id=”position”/>
<source id=”normal”/>
<vertices id=”verts”>
<input semantic=”POSITION” source=”#position”/>
</vertices>
<triangles count=”2″ material=”Bricks”>
<input semantic=”VERTEX” source=”#verts” offset=”0″/>
<input semantic=”NORMAL” source=”#normal” offset=”1″/>
<p>
0 0 1 3 2 1
0 0 2 1 3 2
</p>
</triangles>
</mesh>

English
Deutsch
























