add oversampler
This commit is contained in:
347
oversampling/WDL/plush2/pl_read_3ds.cpp
Normal file
347
oversampling/WDL/plush2/pl_read_3ds.cpp
Normal file
@@ -0,0 +1,347 @@
|
||||
/******************************************************************************
|
||||
Plush Version 1.2
|
||||
read_3ds.c
|
||||
3DS Object Reader
|
||||
Copyright (c) 1996-2000, Justin Frankel
|
||||
******************************************************************************/
|
||||
|
||||
#include "plush.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
pl_uInt16 id;
|
||||
void (*func)(pl_uChar *ptr, pl_uInt32 p);
|
||||
} _pl_3DSChunk;
|
||||
|
||||
static pl_Obj *obj;
|
||||
static pl_Obj *bobj;
|
||||
static pl_Obj *lobj;
|
||||
static pl_sInt16 currentobj;
|
||||
static pl_Mat *_m;
|
||||
|
||||
static pl_Float _pl3DSReadFloat(pl_uChar **ptr);
|
||||
static pl_uInt32 _pl3DSReadDWord(pl_uChar **ptr);
|
||||
static pl_uInt16 _pl3DSReadWord(pl_uChar **ptr);
|
||||
static void _pl3DSChunkReader(pl_uChar *ptr, int len);
|
||||
static void _pl3DSRGBFReader(pl_uChar *f, pl_uInt32 p);
|
||||
static void _pl3DSRGBBReader(pl_uChar *f, pl_uInt32 p);
|
||||
static int _pl3DSASCIIZReader(pl_uChar *ptr, pl_uInt32 p, char *as);
|
||||
static void _pl3DSObjBlockReader(pl_uChar *ptr, pl_uInt32 p);
|
||||
static void _pl3DSTriMeshReader(pl_uChar *f, pl_uInt32 p);
|
||||
static void _pl3DSVertListReader(pl_uChar *f, pl_uInt32 p);
|
||||
static void _pl3DSFaceListReader(pl_uChar *f, pl_uInt32 p);
|
||||
static void _pl3DSFaceMatReader(pl_uChar *f, pl_uInt32 p);
|
||||
static void MapListReader(pl_uChar *f, pl_uInt32 p);
|
||||
static pl_sInt16 _pl3DSFindChunk(pl_uInt16 id);
|
||||
|
||||
static _pl_3DSChunk _pl3DSChunkNames[] = {
|
||||
{0x4D4D,NULL}, /* Main */
|
||||
{0x3D3D,NULL}, /* Object Mesh */
|
||||
{0x4000,_pl3DSObjBlockReader},
|
||||
{0x4100,_pl3DSTriMeshReader},
|
||||
{0x4110,_pl3DSVertListReader},
|
||||
{0x4120,_pl3DSFaceListReader},
|
||||
{0x4130,_pl3DSFaceMatReader},
|
||||
{0x4140,MapListReader},
|
||||
{0xAFFF,NULL}, /* Material */
|
||||
{0xA010,NULL}, /* Ambient */
|
||||
{0xA020,NULL}, /* Diff */
|
||||
{0xA030,NULL}, /* Specular */
|
||||
{0xA200,NULL}, /* Texture */
|
||||
{0x0010,_pl3DSRGBFReader},
|
||||
{0x0011,_pl3DSRGBBReader},
|
||||
};
|
||||
|
||||
pl_Obj *plRead3DSObjFromFile(char *fn, pl_Mat *m)
|
||||
{
|
||||
FILE *f = fopen(fn, "rb");
|
||||
if (!f) return 0;
|
||||
fseek(f, 0, 2);
|
||||
pl_uInt32 p = ftell(f);
|
||||
rewind(f);
|
||||
|
||||
WDL_HeapBuf buf;
|
||||
buf.Resize(p);
|
||||
int s = fread(buf.Get(), 1, p, f);
|
||||
fclose(f);
|
||||
|
||||
if(!s) return 0;
|
||||
|
||||
return plRead3DSObj(buf.Get(), s, m);
|
||||
}
|
||||
|
||||
pl_Obj *plRead3DSObjFromResource(HINSTANCE hInst, int resid, pl_Mat *m)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HRSRC hResource = FindResource(hInst, MAKEINTRESOURCE(resid), "3DS");
|
||||
if(!hResource) return NULL;
|
||||
|
||||
DWORD imageSize = SizeofResource(hInst, hResource);
|
||||
if(imageSize < 6) return NULL;
|
||||
|
||||
HGLOBAL res = LoadResource(hInst, hResource);
|
||||
const void* pResourceData = LockResource(res);
|
||||
if(!pResourceData) return NULL;
|
||||
|
||||
unsigned char *data = (unsigned char *)pResourceData;
|
||||
|
||||
pl_Obj *o = plRead3DSObj(data, imageSize, m);
|
||||
|
||||
DeleteObject(res);
|
||||
|
||||
return o;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
pl_Obj *plRead3DSObj(void *ptr, int size, pl_Mat *m)
|
||||
{
|
||||
_m = m;
|
||||
obj = bobj = lobj = 0;
|
||||
currentobj = 0;
|
||||
|
||||
_pl3DSChunkReader((pl_uChar *)ptr, size);
|
||||
|
||||
return bobj;
|
||||
}
|
||||
|
||||
static pl_Float _pl3DSReadFloat(pl_uChar **ptr) {
|
||||
pl_uInt32 *i;
|
||||
pl_IEEEFloat32 c;
|
||||
i = (pl_uInt32 *) &c;
|
||||
*i = _pl3DSReadDWord(ptr);
|
||||
return ((pl_Float) c);
|
||||
}
|
||||
|
||||
static pl_uInt32 _pl3DSReadDWord(pl_uChar **ptr)
|
||||
{
|
||||
pl_uInt32 r;
|
||||
pl_uChar *p = *ptr;
|
||||
r = *p++;
|
||||
r |= (*p++)<<8;
|
||||
r |= (*p++)<<16;
|
||||
r |= (*p++)<<24;
|
||||
*ptr += 4;
|
||||
return r;
|
||||
}
|
||||
|
||||
static pl_uInt16 _pl3DSReadWord(pl_uChar **ptr)
|
||||
{
|
||||
pl_uInt16 r;
|
||||
pl_uChar *p = *ptr;
|
||||
r = *p++;
|
||||
r |= (*p++)<<8;
|
||||
*ptr += 2;
|
||||
return r;
|
||||
}
|
||||
|
||||
static void _pl3DSRGBFReader(pl_uChar *f, pl_uInt32 p)
|
||||
{
|
||||
pl_Float c[3];
|
||||
if(p < 3*4) return;
|
||||
c[0] = _pl3DSReadFloat(&f);
|
||||
c[1] = _pl3DSReadFloat(&f);
|
||||
c[2] = _pl3DSReadFloat(&f);
|
||||
}
|
||||
|
||||
static void _pl3DSRGBBReader(pl_uChar *f, pl_uInt32 p)
|
||||
{
|
||||
unsigned char c[3];
|
||||
if(p < 3) return;
|
||||
memcpy(c, f, sizeof(c));
|
||||
}
|
||||
|
||||
static int _pl3DSASCIIZReader(pl_uChar *ptr, pl_uInt32 p, char *as)
|
||||
{
|
||||
int l = 0;
|
||||
while (*ptr && p>0)
|
||||
{
|
||||
if(as) *as++ = *ptr;
|
||||
ptr++;
|
||||
l++;
|
||||
p--;
|
||||
}
|
||||
if(as) *as = 0;
|
||||
return l+1;
|
||||
}
|
||||
|
||||
static void _pl3DSObjBlockReader(pl_uChar *ptr, pl_uInt32 p)
|
||||
{
|
||||
int l = _pl3DSASCIIZReader(ptr, p, 0);
|
||||
ptr += l;
|
||||
p -= l;
|
||||
_pl3DSChunkReader(ptr, p);
|
||||
}
|
||||
|
||||
static void _pl3DSTriMeshReader(pl_uChar *ptr, pl_uInt32 p)
|
||||
{
|
||||
pl_uInt32 i;
|
||||
pl_Face *face;
|
||||
obj = new pl_Obj;
|
||||
_pl3DSChunkReader(ptr, p);
|
||||
i = obj->Faces.GetSize();
|
||||
face = obj->Faces.Get();
|
||||
while (i--)
|
||||
{
|
||||
pl_Vertex *vp=obj->Vertices.Get();
|
||||
pl_Vertex *fVertices[3] = {
|
||||
vp+face->VertexIndices[0],
|
||||
vp+face->VertexIndices[1],
|
||||
vp+face->VertexIndices[2],
|
||||
};
|
||||
face->MappingU[0][0] = fVertices[0]->xformedx;
|
||||
face->MappingV[0][0] = fVertices[0]->xformedy;
|
||||
face->MappingU[0][1] = fVertices[1]->xformedx;
|
||||
face->MappingV[0][1] = fVertices[1]->xformedy;
|
||||
face->MappingU[0][2] = fVertices[2]->xformedx;
|
||||
face->MappingV[0][2] = fVertices[2]->xformedy;
|
||||
face++;
|
||||
}
|
||||
obj->CalculateNormals();
|
||||
if (currentobj == 0)
|
||||
{
|
||||
currentobj = 1;
|
||||
lobj = bobj = obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
lobj->Children.Add(obj);
|
||||
lobj = obj;
|
||||
}
|
||||
}
|
||||
|
||||
static void _pl3DSVertListReader(pl_uChar *f, pl_uInt32 p)
|
||||
{
|
||||
pl_uInt16 nv;
|
||||
pl_Vertex *v;
|
||||
int len = (int)p;
|
||||
nv = _pl3DSReadWord(&f);
|
||||
len -= 2;
|
||||
if(len <= 0) return;
|
||||
obj->Vertices.Resize(nv);
|
||||
v = obj->Vertices.Get();
|
||||
while (nv--)
|
||||
{
|
||||
memset(v,0,sizeof(pl_Vertex));
|
||||
v->x = _pl3DSReadFloat(&f);
|
||||
v->y = _pl3DSReadFloat(&f);
|
||||
v->z = _pl3DSReadFloat(&f);
|
||||
len -= 3*4;
|
||||
if(len < 0) return;
|
||||
v++;
|
||||
}
|
||||
}
|
||||
|
||||
static void _pl3DSFaceListReader(pl_uChar *f, pl_uInt32 p)
|
||||
{
|
||||
pl_uInt16 nv;
|
||||
pl_uInt16 c[3];
|
||||
pl_uInt16 flags;
|
||||
pl_Face *face;
|
||||
int len = (int)p;
|
||||
|
||||
nv = _pl3DSReadWord(&f);
|
||||
len -= 2;
|
||||
if(len <= 0) return;
|
||||
obj->Faces.Resize(nv);
|
||||
face = obj->Faces.Get();
|
||||
while (nv--)
|
||||
{
|
||||
memset(face,0,sizeof(pl_Face));
|
||||
c[0] = _pl3DSReadWord(&f);
|
||||
c[1] = _pl3DSReadWord(&f);
|
||||
c[2] = _pl3DSReadWord(&f);
|
||||
flags = _pl3DSReadWord(&f);
|
||||
len -= 4*2;
|
||||
if(len < 0) return;
|
||||
|
||||
face->VertexIndices[0] = (c[0]&0x0000FFFF);
|
||||
face->VertexIndices[1] = (c[1]&0x0000FFFF);
|
||||
face->VertexIndices[2] = (c[2]&0x0000FFFF);
|
||||
face->Material = _m;
|
||||
face++;
|
||||
}
|
||||
if(len) _pl3DSChunkReader(f, len);
|
||||
}
|
||||
|
||||
static void _pl3DSFaceMatReader(pl_uChar *ptr, pl_uInt32 p)
|
||||
{
|
||||
pl_uInt16 n, nf;
|
||||
|
||||
int l = _pl3DSASCIIZReader(ptr, p, 0);
|
||||
ptr += l;
|
||||
p -= l;
|
||||
|
||||
n = _pl3DSReadWord(&ptr);
|
||||
while (n--)
|
||||
{
|
||||
nf = _pl3DSReadWord(&ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static void MapListReader(pl_uChar *f, pl_uInt32 p)
|
||||
{
|
||||
pl_uInt16 nv;
|
||||
pl_Float c[2];
|
||||
pl_Vertex *v;
|
||||
int len = (int) p;
|
||||
nv = _pl3DSReadWord(&f);
|
||||
len -= 2;
|
||||
v = obj->Vertices.Get();
|
||||
if (nv == obj->Vertices.GetSize()) while (nv--)
|
||||
{
|
||||
c[0] = _pl3DSReadFloat(&f);
|
||||
c[1] = _pl3DSReadFloat(&f);
|
||||
len -= 2*4;
|
||||
if (len < 0) return;
|
||||
v->xformedx = c[0];
|
||||
v->xformedy = c[1];
|
||||
v++;
|
||||
}
|
||||
}
|
||||
|
||||
static pl_sInt16 _pl3DSFindChunk(pl_uInt16 id)
|
||||
{
|
||||
pl_sInt16 i;
|
||||
for (i = 0; i < sizeof(_pl3DSChunkNames)/sizeof(_pl3DSChunkNames[0]); i++)
|
||||
if (id == _pl3DSChunkNames[i].id) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void _pl3DSChunkReader(pl_uChar *ptr, int len)
|
||||
{
|
||||
pl_uInt32 hlen;
|
||||
pl_uInt16 hid;
|
||||
pl_sInt16 n;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
hid = _pl3DSReadWord(&ptr);
|
||||
len -= 2;
|
||||
if(len <= 0) return;
|
||||
hlen = _pl3DSReadDWord(&ptr);
|
||||
len -= 4;
|
||||
if(len <= 0) return;
|
||||
if (hlen == 0) return;
|
||||
hlen -= 6;
|
||||
n = _pl3DSFindChunk(hid);
|
||||
if (n < 0)
|
||||
{
|
||||
ptr += hlen;
|
||||
len -= hlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
pl_uChar *p = ptr;
|
||||
if (_pl3DSChunkNames[n].func != NULL)
|
||||
_pl3DSChunkNames[n].func(p, hlen);
|
||||
else
|
||||
_pl3DSChunkReader(p, hlen);
|
||||
|
||||
ptr += hlen;
|
||||
len -= hlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user