/*******************************************************************************/ /* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ /* */ #include "3d.h" #include "types.h" #include "video.h" #include "string.h" /*******************************************************************************/ /* Crée une projection simple pour test */ void proj(vector4 list[], vertex2d plane[], vector4 origin[], u16 number, float factor) { for (u32 i = 0; i < number; i++) { plane[i].x = (int) ((list[i].x * factor) / (list[i].z + origin->z) + origin->x); plane[i].y = (int) ((list[i].y * factor) / (list[i].z + origin->z) + origin->y); } } /*******************************************************************************/ /* Crée une liste de vertex3D pour un cube */ void cube(model3d * model, vector4 * origin, u16 size) { strcpy("cube", model->name); model->vertexnb = 8; model->vertexlist = 0x00300000; model->vertexlist[0].x = origin->x; model->vertexlist[0].y = origin->y; model->vertexlist[0].z = origin->z; model->vertexlist[0].w = 1.0f; model->vertexlist[1].x = origin->x + size; model->vertexlist[1].y = origin->y; model->vertexlist[1].z = origin->z; model->vertexlist[1].w = 1.0f; model->vertexlist[2].x = origin->x; model->vertexlist[2].y = origin->y + size; model->vertexlist[2].z = origin->z; model->vertexlist[2].w = 1.0f; model->vertexlist[3].x = origin->x + size; model->vertexlist[3].y = origin->y + size; model->vertexlist[3].z = origin->z; model->vertexlist[3].w = 1.0f; model->vertexlist[4].x = origin->x; model->vertexlist[4].y = origin->y; model->vertexlist[4].z = origin->z + size; model->vertexlist[4].w = 1.0f; model->vertexlist[5].x = origin->x + size; model->vertexlist[5].y = origin->y; model->vertexlist[5].z = origin->z + size; model->vertexlist[5].w = 1.0f; model->vertexlist[6].x = origin->x; model->vertexlist[6].y = origin->y + size; model->vertexlist[6].z = origin->z + size; model->vertexlist[6].w = 1.0f; model->vertexlist[7].x = origin->x + size; model->vertexlist[7].y = origin->y + size; model->vertexlist[7].z = origin->z + size; model->vertexlist[7].w = 1.0f; model->facelist = 0x00310000; model->facelist[0].V1 = 0; model->facelist[0].V2 = 1; model->facelist[0].V3 = 3; model->facelist[1].V1 = 0; model->facelist[1].V2 = 2; model->facelist[1].V3 = 3; model->facelist[2].V1 = 4; model->facelist[2].V2 = 5; model->facelist[2].V3 = 7; model->facelist[3].V1 = 4; model->facelist[3].V2 = 6; model->facelist[3].V3 = 7; model->facelist[4].V1 = 0; model->facelist[4].V2 = 1; model->facelist[4].V3 = 5; model->facelist[5].V1 = 0; model->facelist[5].V2 = 1; model->facelist[5].V3 = 4; model->facelist[6].V1 = 0; model->facelist[6].V2 = 0; model->facelist[6].V3 = 0; model->facelist[7].V1 = 0; model->facelist[7].V2 = 0; model->facelist[7].V3 = 0; model->facelist[8].V1 = 0; model->facelist[8].V2 = 0; model->facelist[8].V3 = 0; model->facelist[9].V1 = 0; model->facelist[9].V2 = 0; model->facelist[9].V3 = 0; model->facelist[10].V1 = 0; model->facelist[10].V2 = 0; model->facelist[10].V3 = 0; model->facelist[11].V1 = 0; model->facelist[11].V2 = 0; model->facelist[11].V3 = 0; } /*******************************************************************************/ /* Affiche un modèle 3D */ void show3dmodel(model3d * model, matrix44 * transformation, vector4 origin[], float factor, type3D type) { u16 i; vertex2d *plane = 0x00250000; for (i = 0; i < model->vertexnb; i++) { matrix44_transform(transformation, &model->vertexlist[i]); } proj(model->vertexlist, plane, origin, model->vertexnb, factor); switch (type) { case TYPE3D_POINTS: for (i = 0; i < model->vertexnb; i++) { v_writepxl(&plane[i], egatorgb(4)); } break; case TYPE3D_LINES: for (i = 0; i < model->facenb; i++) { v_line(&plane[model->facelist[i].V1], &plane[model->facelist[i].V2], egatorgb(4)); v_line(&plane[model->facelist[i].V1], &plane[model->facelist[i].V3], egatorgb(4)); v_line(&plane[model->facelist[i].V2], &plane[model->facelist[i].V3], egatorgb(4)); } break; case TYPE3D_FACES: break; case TYPE3D_FLAT: break; case TYPE3D_TEXTURE: break; } } /*******************************************************************************/ /* Charge un fichier 3DS */ int load3ds(u8 * pointer, u32 size, model3d * model) { u8 *ptr = pointer; u16 chunk_id; u32 chunk_size; u16 i; float *listfloat; u16 *listunsigned; dsState state = DS_READ_CHUNK_ID; bool dsfile = false; while (ptr - pointer < size) { switch (state) { case DS_READ_CHUNK_ID: chunk_id = *((u16 *) ptr); ptr += 2; state = DS_READ_CHUNK_LENGTH; break; case DS_READ_CHUNK_LENGTH: chunk_size = *((u32 *) ptr); ptr += 4; switch (chunk_id) { case MAIN3DS: dsfile = true; ptr += 10; state = DS_READ_CHUNK_ID; break; case EDIT3DS: state = DS_READ_CHUNK_ID; break; case OBJ_TRIMESH: state = DS_READ_CHUNK_ID; break; case EDIT_OBJECT: state = DS_READ_OBJECT_NAME; break; case TRI_VERTEXL: state = DS_READ_POINT_COUNT; break; case TRI_FACEL1: state = DS_READ_FACE_COUNT; break; case TRI_LOCAL: state = DS_READ_MATRIX; break; default: if (!dsfile) return 1; ptr += (chunk_size - 6); state = DS_READ_CHUNK_ID; break; } break; case DS_READ_OBJECT_NAME: strcpy(ptr, model->name); ptr += (strlen(ptr) + 1); state = DS_READ_CHUNK_ID; break; case DS_SKIP_CHUNK: break; case DS_READ_POINT_COUNT: model->vertexnb = *((u16 *) ptr); state = DS_READ_POINTS; ptr += 2; break; case DS_READ_POINTS: i = 0; listfloat = ptr; model->vertexlist = 0x00300000; while (i < model->vertexnb) { model->vertexlist[i].x = *(listfloat++); model->vertexlist[i].y = *(listfloat++); model->vertexlist[i].z = *(listfloat++); model->vertexlist[i++].w = 1.0; } ptr = listfloat; state = DS_READ_CHUNK_ID; break; case DS_READ_FACE_COUNT: model->facenb = *((u16 *) ptr); state = DS_READ_FACES; ptr += 2; break; case DS_READ_FACES: i = 0; listunsigned = ptr; model->facelist = 0x00400000; while (i < model->facenb) { model->facelist[i].V1 = *(listunsigned++); model->facelist[i].V2 = *(listunsigned++); model->facelist[i++].V3 = *(listunsigned++); listunsigned++; } ptr = listunsigned; state = DS_READ_CHUNK_ID; break; case DS_READ_MATRIX: i = 0; listfloat = ptr; while (i < 4) { model->view.V[i].x = *(listfloat++); model->view.V[i].y = *(listfloat++); model->view.V[i].z = *(listfloat++); model->view.V[i++].w = 0.0f; } model->view.V[3].w = 1.0f; ptr = listfloat; state = DS_READ_CHUNK_ID; break; case DS_READ_DONE: break; } } }