256 lines
8.4 KiB
C
256 lines
8.4 KiB
C
/*******************************************************************************/
|
|
/* 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;
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|