2018-09-28 20:35:51 +02:00
|
|
|
/*******************************************************************************/
|
|
|
|
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
|
|
|
|
/* */
|
2018-08-17 16:46:56 +02:00
|
|
|
#include "3d.h"
|
2018-09-28 20:35:51 +02:00
|
|
|
#include "types.h"
|
|
|
|
#include "video.h"
|
2018-11-01 01:12:30 +01:00
|
|
|
#include "string.h"
|
2018-09-28 20:35:51 +02:00
|
|
|
|
2018-10-26 14:09:43 +02:00
|
|
|
/*******************************************************************************/
|
|
|
|
/* Crée une projection simple pour test */
|
2018-12-12 15:25:04 +01:00
|
|
|
void proj(vector4 list[], vertex2d plane[], vector4 origin[], u16 number,
|
|
|
|
float factor)
|
2018-10-26 14:09:43 +02:00
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
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);
|
|
|
|
}
|
2018-10-26 14:09:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Crée une liste de vertex3D pour un cube */
|
|
|
|
|
2018-12-12 15:25:04 +01:00
|
|
|
void cube(model3d * model, vector4 * origin, u16 size)
|
2018-10-26 14:09:43 +02:00
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
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;
|
2018-11-01 19:19:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Affiche un modèle 3D */
|
|
|
|
|
2018-12-12 15:25:04 +01:00
|
|
|
void show3dmodel(model3d * model, matrix44 * transformation,
|
|
|
|
vector4 origin[], float factor, type3D type)
|
2018-11-01 19:19:29 +01:00
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
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;
|
|
|
|
}
|
2018-10-26 14:09:43 +02:00
|
|
|
}
|
2018-10-30 19:21:18 +01:00
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
/* Charge un fichier 3DS */
|
|
|
|
|
2018-12-12 15:25:04 +01:00
|
|
|
int load3ds(u8 * pointer, u32 size, model3d * model)
|
2018-10-30 19:21:18 +01:00
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
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)
|
2018-11-01 01:12:30 +01:00
|
|
|
{
|
2018-12-12 15:25:04 +01:00
|
|
|
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;
|
|
|
|
|
|
|
|
}
|
2018-10-30 19:21:18 +01:00
|
|
|
|
2018-12-12 15:25:04 +01:00
|
|
|
}
|
|
|
|
}
|