|
|
@@ -0,0 +1,230 @@ |
|
|
#include <sys/stat.h> |
|
|
#include <sys/mman.h> |
|
|
#include <fcntl.h> |
|
|
#include <unistd.h> |
|
|
#include <stdlib.h> |
|
|
#include <stdio.h> |
|
|
|
|
|
struct xyz |
|
|
{ |
|
|
float x, y, z; |
|
|
}; |
|
|
|
|
|
struct uv |
|
|
{ |
|
|
float u, v; |
|
|
}; |
|
|
|
|
|
struct triangle |
|
|
{ |
|
|
unsigned short a, b, c; |
|
|
}; |
|
|
|
|
|
struct source |
|
|
{ |
|
|
int number_of_verts; |
|
|
|
|
|
struct xyz *xyz_coords; |
|
|
struct uv *uv_coords; |
|
|
}; |
|
|
|
|
|
struct material |
|
|
{ |
|
|
int number_of_tris; |
|
|
int source_index; |
|
|
|
|
|
struct triangle *tris; |
|
|
}; |
|
|
|
|
|
struct model |
|
|
{ |
|
|
int bucket_levels; |
|
|
int number_of_sources; |
|
|
int number_of_materials; |
|
|
|
|
|
struct source *sources; |
|
|
struct material *materials; |
|
|
}; |
|
|
|
|
|
int open_n3m (struct model *m, void *data) |
|
|
{ |
|
|
char *magic = (char*)data; |
|
|
printf("magic: %c%c%c\n", magic[0], magic[1], magic[2]); |
|
|
if (magic[0] != 'N' || magic[1] != '3' || magic[2] != 'M') { |
|
|
return -1; |
|
|
} |
|
|
|
|
|
char version = magic[3]; |
|
|
printf("version: %c\n", version); |
|
|
|
|
|
int *header = (int*)data; |
|
|
m->number_of_sources = header[1]; |
|
|
m->number_of_materials = header[2]; |
|
|
printf("number_of_sources: %d\n", m->number_of_sources); |
|
|
printf("number_of_materials: %d\n", m->number_of_materials); |
|
|
|
|
|
m->sources = calloc(m->number_of_sources, sizeof(struct source)); |
|
|
m->materials = calloc(m->number_of_materials, sizeof(struct material)); |
|
|
|
|
|
int i = 0; |
|
|
for (i = 0; i < m->number_of_sources; i++) { |
|
|
struct source *s = &m->sources[i]; |
|
|
|
|
|
int offset = i * 2 + 3; |
|
|
|
|
|
int data_offset = header[offset]; |
|
|
s->number_of_verts = header[offset + 1]; |
|
|
|
|
|
printf("data_offset: %d\n", data_offset); |
|
|
printf("source[%d].number_of_verts: %d\n", i, s->number_of_verts); |
|
|
|
|
|
s->xyz_coords = (struct xyz*)((char*)data + data_offset); |
|
|
s->uv_coords = (struct uv*)((char*)data + data_offset + s->number_of_verts * 12); |
|
|
} |
|
|
|
|
|
for (i = 0; i < m->number_of_materials; i++) { |
|
|
struct material *mat = &m->materials[i]; |
|
|
|
|
|
int offset = m->number_of_sources * 2 + i * 4 + 3; |
|
|
|
|
|
int indices_offset = header[offset]; |
|
|
|
|
|
mat->number_of_tris = header[offset + 1]; |
|
|
mat->source_index = header[offset + 2]; |
|
|
mat->tris = (struct triangle*)((char*)data + indices_offset); |
|
|
|
|
|
printf("material[%d].number_of_tris: %d\n", i, mat->number_of_tris); |
|
|
printf("material[%d].source_index: %d\n", i, mat->source_index); |
|
|
} |
|
|
|
|
|
return 0; |
|
|
} |
|
|
|
|
|
int save_dae (struct model *m, FILE *f) |
|
|
{ |
|
|
fprintf(f, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"); |
|
|
fprintf(f, "<COLLADA xmlns=\"http://www.collada.org/2005/11/COLLADASchema\" version=\"1.4.1\">\n"); |
|
|
fprintf(f, " <asset>\n"); |
|
|
fprintf(f, " <contributor>\n"); |
|
|
fprintf(f, " <authoring_tool>n3mtodae</authoring_tool>\n"); |
|
|
fprintf(f, " </contributor>\n"); |
|
|
fprintf(f, " <created>2012-01-21T04:10:34Z</created>\n"); |
|
|
fprintf(f, " <modified>2012-01-21T04:10:34Z</modified>\n"); |
|
|
fprintf(f, " <unit meter=\"0.0254000\" name=\"inch\" />\n"); |
|
|
fprintf(f, " <up_axis>X_UP</up_axis>\n"); |
|
|
fprintf(f, " </asset>\n"); |
|
|
|
|
|
fprintf(f, " <library_visual_scenes>\n"); |
|
|
fprintf(f, " <visual_scene id=\"ID1VISUALSCENE\">\n"); |
|
|
fprintf(f, " <node name=\"n3mtodae\">\n"); |
|
|
int i = 0; |
|
|
for (i = 0; i < m->number_of_materials; i++) { |
|
|
struct material *mat = &m->materials[i]; |
|
|
|
|
|
fprintf(f, " <instance_geometry url=\"#ID%pGEOMETRY\">\n", mat); |
|
|
|
|
|
fprintf(f, " <bind_material>\n"); |
|
|
fprintf(f, " <technique_common>\n"); |
|
|
fprintf(f, " <instance_material symbol=\"Material2\" target=\"#ID4\">\n"); |
|
|
fprintf(f, " <bind_vertex_input semantic=\"UVSET0\" input_semantic=\"TEXCOORD\" input_set=\"0\" />\n"); |
|
|
fprintf(f, " </instance_material>\n"); |
|
|
fprintf(f, " </technique_common>\n"); |
|
|
fprintf(f, " </bind_material>\n"); |
|
|
|
|
|
fprintf(f, " </instance_geometry>\n"); |
|
|
} |
|
|
fprintf(f, " </node>\n"); |
|
|
fprintf(f, " </visual_scene>\n"); |
|
|
fprintf(f, " </library_visual_scenes>\n"); |
|
|
|
|
|
fprintf(f, " <library_geometries>\n"); |
|
|
for (i = 0; i < m->number_of_materials; i++) { |
|
|
struct material *mat = &m->materials[i]; |
|
|
struct source *src = &m->sources[mat->source_index]; |
|
|
|
|
|
fprintf(f, " <geometry id=\"ID%pGEOMETRY\">\n", mat); |
|
|
fprintf(f, " <mesh>\n"); |
|
|
|
|
|
fprintf(f, " <source id=\"ID%pSOURCE\">\n", src->xyz_coords); |
|
|
fprintf(f, " <float_array id=\"ID%pARRAY\" count=\"%d\">", src->xyz_coords, src->number_of_verts * 3); |
|
|
int j = 0; |
|
|
for (j = 0; j < src->number_of_verts; j++) { |
|
|
fprintf(f, "%g %g %g ", src->xyz_coords[j].x, src->xyz_coords[j].y, src->xyz_coords[j].z); |
|
|
} |
|
|
fprintf(f, "</float_array>\n"); |
|
|
fprintf(f, " <technique_common>\n"); |
|
|
fprintf(f, " <accessor count=\"%d\" source=\"#ID%pARRAY\" stride=\"3\">\n", src->number_of_verts, src->xyz_coords); |
|
|
fprintf(f, " <param name=\"X\" type=\"float\" />\n"); |
|
|
fprintf(f, " <param name=\"Y\" type=\"float\" />\n"); |
|
|
fprintf(f, " <param name=\"Z\" type=\"float\" />\n"); |
|
|
fprintf(f, " </accessor>\n"); |
|
|
fprintf(f, " </technique_common>\n"); |
|
|
fprintf(f, " </source>\n"); |
|
|
|
|
|
fprintf(f, " <vertices id=\"ID%pVERTICES\">\n", mat); |
|
|
fprintf(f, " <input semantic=\"POSITION\" source=\"#ID%pSOURCE\" />\n", src->xyz_coords); |
|
|
fprintf(f, " </vertices>\n"); |
|
|
|
|
|
fprintf(f, " <triangles count=\"%d\" material=\"Material2\">\n", mat->number_of_tris); |
|
|
fprintf(f, " <input offset=\"0\" semantic=\"VERTEX\" source=\"#ID%pVERTICES\" />\n", mat); |
|
|
fprintf(f, " <p>"); |
|
|
|
|
|
for (j = 0; j < mat->number_of_tris; j++) { |
|
|
fprintf(f, "%d %d %d ", mat->tris[j].a, mat->tris[j].b, mat->tris[j].c); |
|
|
} |
|
|
|
|
|
fprintf(f, "</p>\n"); |
|
|
fprintf(f, " </triangles>\n"); |
|
|
|
|
|
fprintf(f, " </mesh>\n"); |
|
|
fprintf(f, " </geometry>\n"); |
|
|
} |
|
|
fprintf(f, " </library_geometries>\n"); |
|
|
|
|
|
fprintf(f, " <library_materials>\n"); |
|
|
fprintf(f, " <material id=\"ID4\" name=\"material\">\n"); |
|
|
fprintf(f, " <instance_effect url=\"#ID3\" />\n"); |
|
|
fprintf(f, " </material>\n"); |
|
|
fprintf(f, " </library_materials>\n"); |
|
|
|
|
|
fprintf(f, " <library_effects>\n"); |
|
|
fprintf(f, " <effect id=\"ID3\">\n"); |
|
|
fprintf(f, " <profile_COMMON>\n"); |
|
|
fprintf(f, " <technique sid=\"COMMON\">\n"); |
|
|
fprintf(f, " <lambert>\n"); |
|
|
fprintf(f, " <diffuse>\n"); |
|
|
fprintf(f, " <color>1.0000000 1.0000000 1.0000000 1.0000000</color>\n"); |
|
|
fprintf(f, " </diffuse>\n"); |
|
|
fprintf(f, " </lambert>\n"); |
|
|
fprintf(f, " </technique>\n"); |
|
|
fprintf(f, " </profile_COMMON>\n"); |
|
|
fprintf(f, " </effect>\n"); |
|
|
fprintf(f, " </library_effects>\n"); |
|
|
|
|
|
fprintf(f, " <scene>\n"); |
|
|
fprintf(f, " <instance_visual_scene url=\"#ID1VISUALSCENE\" />\n"); |
|
|
fprintf(f, " </scene>\n"); |
|
|
|
|
|
fprintf(f, "</COLLADA>\n"); |
|
|
|
|
|
return 0; |
|
|
} |
|
|
|
|
|
int main() |
|
|
{ |
|
|
int fd = open("/Users/fak/Desktop/Nokia3D/b.n3m", O_RDONLY); |
|
|
struct stat sb = {0}; |
|
|
fstat(fd, &sb); |
|
|
|
|
|
void *data = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); |
|
|
|
|
|
struct model m; |
|
|
|
|
|
open_n3m (&m, data); |
|
|
|
|
|
FILE *out = fopen("/Users/fak/Desktop/Nokia3D/b.dae", "w"); |
|
|
save_dae (&m, out); |
|
|
|
|
|
return 0; |
|
|
} |
|
|
|