⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 3dsload.c

📁 任意给定三维空间的点集
💻 C
字号:
/* *  3D Studio object reader */#define FILELOAD#define MEMLOAD#include <stdlib.h>#include <string.h>#include <setjmp.h>#include "3dsload.h"static void  (* dread)  (void * dest, int len);static void  (* dsetpos)(dword pos);static dword (* dgetpos)(void);static jmp_buf EnvState;#ifdef FILELOAD#include <stdio.h>static FILE * InFile=0;static void FileRead(void * dest, int len){	if(fread(dest, len, 1, InFile) != 1) {		//printf("Error reading file\n");		longjmp(EnvState, 1);	}}static void FileSetpos(dword pos){	if(fseek(InFile, (long)pos, SEEK_SET) != 0) {		//printf("Error moving filepointer\n");		longjmp(EnvState, 1);	}}static dword FileGetpos(void){	long pos;	if((pos=ftell(InFile)) == -1L) {		//printf("Error getting fileposition\n");		longjmp(EnvState, 1);	}	return (dword) pos;}#endif#ifdef MEMLOADstatic byte * MemBuffer=0;static dword MemBufferLen=0, MemBufferIndex=0;static void MemRead(void * dest, int len){	// Never allow any reads past the membuffer.	if(MemBufferIndex+len > MemBufferLen) {		//printf("Bad memread\n");		longjmp(EnvState, 1);	}	memcpy(dest, &MemBuffer[MemBufferIndex], len);	MemBufferIndex+=len;}static void MemSetpos(dword pos){	// It should be legal to move the position one byte	// past the membuffer. The mem must not be read though.	if(pos > MemBufferLen) {		//printf("Bad memsetpos\n");		longjmp(EnvState, 1);	}	MemBufferIndex=pos;}static dword MemGetpos(void){	return MemBufferIndex;}#endifstatic H3dsScene * Scene;H3dsMeshObj * GetMeshObj(void){	void * mem;	if((mem=realloc(Scene->meshobjlist,					sizeof(H3dsMeshObj)*(Scene->meshobjs+1))) == 0) {		//printf("Error reallocating mem\n");		longjmp(EnvState, 1);	}	Scene->meshobjlist=(H3dsMeshObj *) mem;	H3dsMeshObj * obj=&Scene->meshobjlist[Scene->meshobjs++];	memset(obj, 0, sizeof(H3dsMeshObj));	return obj;}static void * getmem(int size){	void * mem;	if((mem=malloc(size))==0) {		//printf("Error allocating mem\n");		longjmp(EnvState, 1);	}	return mem;}// Each 3DS data-chunk starts with a 6 byte header.// The first item in the header is a 2 byte (word) id-number.// After that follows a dword wich gives the size of// the data-chunk including the header. The size can be used// as an relative offset to the next chunk.// tab 4enum {	CHUNK_RGBF      	= 0x0010,	CHUNK_RGBB      	= 0x0011,//  CHUNK_RBGB2     	= 0x0012,	// ?? NOT HLS.	CHUNK_MAIN      	= 0x4D4D,     CHUNK_OBJMESH      = 0x3D3D,      CHUNK_BKGCOLOR    = 0x1200,	  CHUNK_AMBCOLOR  	= 0x2100,	  CHUNK_OBJBLOCK  	= 0x4000,	   CHUNK_TRIMESH   	= 0x4100,		CHUNK_VERTLIST  = 0x4110,		CHUNK_FACELIST  = 0x4120,		CHUNK_FACEMAT   = 0x4130,		CHUNK_MAPLIST   = 0x4140,		CHUNK_SMOOLIST  = 0x4150,		CHUNK_TRMATRIX  = 0x4160,	   CHUNK_LIGHT     	= 0x4600,		CHUNK_SPOTLIGHT = 0x4610,	   CHUNK_CAMERA    	= 0x4700,	 CHUNK_MATERIAL  	= 0xAFFF,	  CHUNK_MATNAME   	= 0xA000,	  CHUNK_AMBIENT   	= 0xA010,	  CHUNK_DIFFUSE   	= 0xA020,	  CHUNK_SPECULAR  	= 0xA030,	  CHUNK_TEXTURE   	= 0xA200,	  CHUNK_BUMPMAP   	= 0xA230,	  CHUNK_MAPFILE   	= 0xA300,	 CHUNK_KEYFRAMER 	= 0xB000,	  CHUNK_FRAMES      = 0xB008};static void ReadVertList(dword, H3dsMeshObj * meshobj){	word nv;	dread(&nv, sizeof(nv));	meshobj->verts=nv;	int k=nv;	meshobj->vertlist=(H3dsVert *) getmem(sizeof(H3dsVert)*k);	for(int n=0; n<k; n++) {		dread(&meshobj->vertlist[n], sizeof(float32)*3);	}}static void ReadFaceList(dword, H3dsMeshObj * meshobj){	word nv;	dread(&nv, sizeof(nv));	meshobj->faces=nv;	int k=nv;	meshobj->facelist=(H3dsFace *) getmem(sizeof(H3dsFace)*k);	for(int n=0; n<k; n++) {		dread(&meshobj->facelist[n], sizeof(word)*4);	}}static void ReadMapList(dword, H3dsMeshObj * meshobj){	word nv;	dread(&nv, sizeof(nv));	meshobj->maps=nv;	int k=nv;	meshobj->maplist=(H3dsMap *) getmem(sizeof(H3dsMap)*k);	for(int n=0; n<k; n++) {		dread(&meshobj->maplist[n], sizeof(float32)*2);	}}static void ReadTraMatrix(dword, H3dsMeshObj * meshobj){	dread(&meshobj->TraMatrix, sizeof(float32)*12);	meshobj->matrix=1;}static void ReadTriMeshBlocks(dword p, char * name){	word id;	dword len, pc;	H3dsMeshObj * meshobj=GetMeshObj();	strcpy(meshobj->name, name);	while((pc=dgetpos()) < p)	{		dread(&id, sizeof(id));		dread(&len, sizeof(len));		switch((int)id)		{			case CHUNK_VERTLIST: ReadVertList (pc+len, meshobj); break;			case CHUNK_FACELIST: ReadFaceList (pc+len, meshobj); break;			case CHUNK_MAPLIST:  ReadMapList  (pc+len, meshobj); break;			case CHUNK_TRMATRIX: ReadTraMatrix(pc+len, meshobj); break;			//case CHUNK_FACEMAT:			//case CHUNK_SMOOLIST:			default: dsetpos(pc+len);		}	}}static void ReadObjBlocks(dword p){	word id;	dword len, pc;	char name[16];	// The object name is the first item	int n=0;	do {		dread(&name[n++], 1);	} while  ( ( name[n-1] != '\0' )                   &&  ( n < (int)sizeof(name) ) );	name[n-1]='\0';	while((pc=dgetpos()) < p)	{		dread(&id, sizeof(id));		dread(&len, sizeof(len));		switch((int)id)		{			case CHUNK_TRIMESH:	ReadTriMeshBlocks(pc+len, name); break;			//case CHUNK_LIGHT:			//case CHUNK_CAMERA:			default: dsetpos(pc+len);		}	}}static void ReadObjMeshBlocks(dword p){	word id;	dword len, pc;	while((pc=dgetpos()) < p)	{		dread(&id, sizeof(id));		dread(&len, sizeof(len));		switch((int)id)		{			case CHUNK_OBJBLOCK: ReadObjBlocks(pc+len); break;			//case CHUNK_AMBCOLOR:			//case CHUNK_BKGCOLOR:			default: dsetpos(pc+len);		}	}}static void ReadMainBlocks(dword p){	word id;	dword len, pc;	while((pc=dgetpos()) < p)	{		dread(&id, sizeof(id));		dread(&len, sizeof(len));		switch((int)id)		{			case CHUNK_OBJMESH: ReadObjMeshBlocks(pc+len); break;			//case CHUNK_MATERIAL:			//case CHUNK_KEYFRAMER:			default: dsetpos(pc+len);		}	}}void HFree3dsScene(H3dsScene * scene){	if(scene) {		if(scene->meshobjlist) {			for(int n=scene->meshobjs-1; n>=0; n--) {				H3dsMeshObj * mobj = &scene->meshobjlist[n];				if(mobj->maplist)  free(mobj->maplist);				if(mobj->facelist) free(mobj->facelist);				if(mobj->vertlist) free(mobj->vertlist);			}			free(scene->meshobjlist);		}		free(scene);	}}H3dsScene * HRead3dsScene(void * ptr, int what, dword size){	if(ptr==0)		return 0;	#ifdef FILELOAD	if(what==0) {		// Load from file		InFile=(FILE *) ptr;		dread=FileRead;		dsetpos=FileSetpos;		dgetpos=FileGetpos;	}	else	#endif	#ifdef MEMLOAD	if(what==1) {		// Read from mem		MemBufferIndex=0;		MemBufferLen=size;		MemBuffer=(byte *) ptr;		dread=MemRead;		dsetpos=MemSetpos;		dgetpos=MemGetpos;	}	else	#endif	{		return 0;	}	if((Scene=(H3dsScene *) malloc(sizeof(H3dsScene)))==0)		return 0;	memset(Scene, 0, sizeof(H3dsScene));	int retval = setjmp(EnvState);	if(retval==0) {		// Return address set, start loading 3DS data.		word id;		dword len, pc;		pc=dgetpos();		dread(&id, sizeof(id));		dread(&len, sizeof(len));		if((int)id!=CHUNK_MAIN) {			HFree3dsScene(Scene);			//printf("Not 3ds data\n");			return 0;		}		ReadMainBlocks(pc+len);	}	else {        // There was an error, free the allocated mem and return NULL.		HFree3dsScene(Scene);		return 0;	}	return Scene;}H3dsScene * ThreeDS_ReadFromFile( const char  * filename ){    FILE  * inf;    H3dsScene   * scene;    scene = NULL;    inf = fopen( filename, "rb");    if  ( inf == NULL ) {        fprintf(stderr, "Failed to open %s\n", filename );        return  NULL;    }    long size;    if( fseek(inf, 0, SEEK_END)) {        fprintf(stderr, "Error seeking %s\n", filename );        fclose( NULL );        return  NULL;    }    size=ftell(inf);    if  ( size == -1L ) {        fprintf(stderr, "Error seeking %s\n", filename );        fclose(inf);        return  NULL;    }    rewind(inf);    scene = HRead3dsScene(inf, 0, size);    if  ( scene == NULL) {        fprintf(stderr, "Failed to load %s\n", filename );        fclose(inf);        return NULL;    }        fclose(inf);    return  scene;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -