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

📄 mlrloadobj.cpp

📁 机甲指挥官2源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// read texture coordinate into list 
			sscanf(next, "%f %f", &t[tCount][0], &t[tCount][1]);

// advance texture coordinate count 
			++tCount;
		} else if (SAME(token, "vc"))
		{
			static Scalar r, g, b, a;
// enlarge color list
			GROW(c, RGBAColor);

// Set default values for color
			r = g = b = 0.0f;
			a = 1.0f;

// read color into list
			sscanf(next, "%f %f %f %f", &r, &g, &b, &a);

			c[cCount] = RGBAColor(r, g, b, a);

// advance color count
			++cCount;
		} else if (SAME(token, "g"))
		{
			++numGroups;

			backface_following_polygons = (strstr(next, " bf_") != 0);
			
			//DEBUG_STREAM << "'g " << next << "' bf=" << 
			//	backface_following_polygons << endl;

		} else if (SAME(token, "f") || SAME(token, "fo"))
		{
			int          count;
			int          textureValid = 1;
			int          normalsValid = 1;
			int          colorsValid = 1;
			int          vi[FACE_SIZE];
			int          ti[FACE_SIZE];
			int          ni[FACE_SIZE];
			int          ci[FACE_SIZE];

			char        *slash;
			char         vertexData[256];

// parse vertex data from input buffer 
			for (count = 0; count < FACE_SIZE; count++)
			{
// read the next vertices' data packet 
				if (sscanf(next, "%s%n", vertexData, &width) != 1)
					break;

// advance next pointer past data packet ("n/n/n") 
				next += width;

// get vertex coordinate index 
				vi[count] = (int)strtol(vertexData, 0, 10);

// get texture coordinate index 
				ti[count] = 0;
				if ((slash = strchr(vertexData, '/')) == 0 ||
					  (ti[count] = (int)strtol(slash+1, 0, 10)) == 0)
					textureValid = 0;

// get vertex normal index 
				ni[count] = 0;
				if (slash == 0 || (slash = strchr(slash+1, '/')) == 0 ||
					  (ni[count] = (int)strtol(slash+1, 0, 10)) == 0)
					normalsValid = 0;

// get color index 
				ci[count] = 0;
				if (slash == 0 || (slash = strchr(slash+1, '/')) == 0 ||
					  (ci[count] = (int)strtol(slash+1, 0, 10)) == 0)
					colorsValid = 0;

// form cannonical indices:
// convert ".obj" 1-based indices to 0-based (subtract 1)
// convert negative indices to positive (count from 0)
					       
				if (vi[count] >= 0)
					vi[count] -= 1;
				else
					vi[count]  += vCount;

				if (ti[count] >= 0)
					ti[count] -= 1;
				else
					ti[count]  += tCount;

				if (ni[count] >= 0)
					ni[count] -= 1;
				else
					ni[count]  += nCount;

				if (ci[count] >= 0)
					ci[count] -= 1;
				else
					ci[count]  += cCount;
			}

			if(count > 2)
			{
// enlarge polygon list 
				GROW(p, Poly);

				p[pCount].nr = count;
				p[pCount].vIndex = new int [p[pCount].nr];

// Setup vertex position  information
				for (i = 0; i < count; i++)
				{
					p[pCount].vIndex[i] = vi[i];
				}

// Setup normal vector information 
				if (normalsValid)
				{
					for (i = 0; i < count; i++)
					{
						p[pCount].nIndex[i] = ni[i];
					}
				}

// Setup color information 
				if (colorsValid)
				{
					p[pCount].cIndex = new int [p[pCount].nr];
					for (i = 0; i < count; i++)
					{
						p[pCount].cIndex[i] = ci[i];
					}
				}

// Setup texture coordinates information 
				if (textureValid)
				{
					p[pCount].tIndex = new int [p[pCount].nr];
					for (i = 0; i < count; i++)
					{
						p[pCount].tIndex[i] = ti[i];
					}
				}

				++pCount;

				numTris += count - 2;
				numPolys++;
			}
		} else if (SAME(token, "usemtl"))
		{
			if(numPrimitives > 0)
			{
				MLRPolyMesh *pm = BuildPolyMesh(p, pCount, v, n, t, c);
				shape->Add(pm);
			}
			numPrimitives++;

			char        mtlName[1024];
			sscanf(next, "%s", mtlName);
			useMtl(mtlName);
		} else if (SAME(token, "mtllib"))
		{
			char        libName[1024];
			sscanf(next, "%s", libName);

			loadMtl(libName);
		} else if (
					  SAME(token, "bevel")      ||
					  SAME(token, "bmat")       ||
					  SAME(token, "bsp")        ||
					  SAME(token, "bzp")        ||
					  SAME(token, "c_interp")   ||
					  SAME(token, "cdc")        ||
					  SAME(token, "con")        ||
					  SAME(token, "cstype")     ||
					  SAME(token, "ctech")      ||
					  SAME(token, "curv")       ||
					  SAME(token, "curv2")      ||
					  SAME(token, "d_interp")   ||
					  SAME(token, "deg")        ||
					  SAME(token, "end")        ||
					  SAME(token, "hole")       ||
					  SAME(token, "l")          ||
					  SAME(token, "lod")        ||
					  SAME(token, "maplib")     ||
					  SAME(token, "mg")         ||
					  SAME(token, "o")          ||
					  SAME(token, "p")          ||
					  SAME(token, "param")      ||
					  SAME(token, "parm")       ||
					  SAME(token, "res")        ||
					  SAME(token, "s")          ||
					  SAME(token, "scrv")       ||
					  SAME(token, "shadow_obj") ||
					  SAME(token, "sp")         ||
					  SAME(token, "stech")      ||
					  SAME(token, "step")       ||
					  SAME(token, "surf")       ||
					  SAME(token, "trace_obj")  ||
					  SAME(token, "trim")       ||
					  SAME(token, "usemap")     ||
					  SAME(token, "vp"))
		{
			++numSkip;
		}
		else
		{
			fprintf(stderr, "unrecognized: %s", buffer);
			++numOther;
		}
	}

// close Wavefront ".obj" file 
	fclose(objFile);

	MLRPolyMesh *pm = BuildPolyMesh(p, pCount, v, n, t, c);
	shape->Add(pm);

// release dynamically allocated vertex, normal, and texture data 
	if (v != 0) free(v);
	if (n != 0) free(n);
	if (t != 0) free(t);
	if (c != 0) free(c);
	if (p != 0) free(p);

//  note -- if you define this, then material files will be read anew
//         for every file that references them. could be slow for big
//         material files and many models. on the other hand, if you
//         don't define it then the lists will linger after the files
//         have all been loaded -- wasting space.
		 
#ifdef        FORGETFUL
// discard material info 
	forgetMaterials();
	forgetMaterialFiles();
#endif

// print statistics 
	//pfNotify(PFNFY_NOTICE, PFNFY_PRINT, "pfdLoadFile_obj: %s", fileName);
	fprintf(stdout, "  Input Data:");
	if (numSkip != 0)
		fprintf(stdout, "    Skipped tokens:     %8ld", numSkip);
	if (numOther != 0)
		fprintf(stdout, "    Unrecognized tokens:%8ld", numOther);
	if (numGroups != 0)
		fprintf(stdout, "    Groups processed:   %8ld", numGroups);
	if (vCount != 0)
		fprintf(stdout, "    Vertex coordinates: %8ld", vCount);
	if (nCount != 0)
		fprintf(stdout, "    Vertex normals:     %8ld", nCount);
	if (tCount != 0)
		fprintf(stdout, "    Texture coordinates:%8ld", tCount);
	if (cCount != 0)
		fprintf(stdout, "    Vertex colors:      %8ld", cCount);
	if (numTris != 0)
		fprintf(stdout, "    Input polygons:     %8ld", numPolys);
	if (numTris != 0)
		fprintf(stdout, "    Total triangles:    %8ld", numTris);

	return shape;
}

// ***
// ***        P R O C E S S    M A T E R I A L    F I L E S
// **

const int MTL_NOT_DEFINED    = 0x0001;
const int MTL_HAS_GEOSTATE   = 0x0002;
const int MTL_HAS_AMBIENT    = 0x0004;
const int MTL_HAS_DIFFUSE    = 0x0008;
const int MTL_HAS_ALPHA      = 0x0010;
const int MTL_HAS_SPECULAR   = 0x0020;
const int MTL_HAS_SHININESS  = 0x0040;
const int MTL_HAS_TEXTURE    = 0x0080;
const int MTL_HAS_REFLECTION = 0x0100;
const int MTL_IS_TWO_SIDED   = 0x0200;

// data for a single wavefront material
 
typedef struct objMaterial
{
	char	library[1024]; // library name
	char	name[1024];    // material name 
	int		defined;               // defined fields 
	RGBColor	ambient;               // Ka field 
	RGBColor diffuse;               // Kd field 
	RGBColor specular;              // Ks field 
	float  alpha;                 // Tr field (actually, 1-Tr) 
	float  shininess;             // Ns field 
	char   texture[1024]; // texture map name 
	float  su;                    // u-axis tc scale 
	float  sv;                    // v-axis tc scale 
	char   reflect[1024]; // reflection mode 
} objMaterial;

static objMaterial        *mtlList      = 0;
static int                 mtlListCount = 0;
static int                 mtlListSize  = 0;

static void
reSetMaterial (objMaterial *m)
{
	if (m == 0)
		return;

	memset(m->library, '\0', sizeof(m->library));
	memset(m->name, '\0', sizeof(m->name));
	m->defined = 0;
	m->ambient = RGBColor ( 0.0f, 0.0f, 0.0f);
	m->diffuse = RGBColor ( 0.0f, 0.0f, 0.0f);
	m->specular = RGBColor (0.0f, 0.0f, 0.0f);
	m->alpha = 1.0f;
	m->shininess = 0.0f;
	memset(m->texture, '\0', sizeof(m->texture));
	m->su = 0.0f;
	m->sv = 0.0f;
	memset(m->reflect, '\0', sizeof(m->reflect));
}

#ifdef        PRINT_MATERIALS_AS_PARSED
static void
	printMtl (objMaterial *m)
{
	if (m == 0)
		return;

	fprintf(stdout, "  library: %s\n", m->library);
	fprintf(stdout, "     name: %s\n", m->name);
	fprintf(stdout, "  defined: 0x%x\n", m->defined);
	fprintf(stdout, "  ambient: %g %g %g\n", 
					m->ambient[0],  m->ambient[1],  m->ambient[2]);
	fprintf(stdout, "  diffuse: %g %g %g\n", 
					m->diffuse[0],  m->diffuse[1],  m->diffuse[2]);
	fprintf(stdout, " specular: %g %g %g\n", 
					m->specular[0], m->specular[1], m->specular[2]);
	fprintf(stdout, "    alpha: %g\n", m->alpha);
	fprintf(stdout, "shininess: %g\n", m->shininess);
	fprintf(stdout, "  texture: %s\n", m->texture);
	fprintf(stdout, "       su: %g\n", m->su);
	fprintf(stdout, "       sv: %g\n", m->sv);
	fprintf(stdout, "  reflect: %s\n", m->reflect);
	fprintf(stdout, "\n");
	fflush (stdout);
}
#endif

static void
rememberMaterial (objMaterial *m)
{
	int                i;

	if (m == 0)
		return;

#ifdef        PRINT_MATERIALS_AS_PARSED
	printMtl (m);
#endif

// check for "empty" definition -- don't add junk 
	if (m->name[0] == '\0' || m->defined == 0)
		return;
		
// look for name in material list -- don't add duplicates 
	for (i = 0; i < mtlListCount; i++)
	if (strcmp(m->name, mtlList[i].name) == 0)
	{
// XXX the best thing is to do a compare and warn user 
// XXX if the old and new definitions are not identical 

		if (
			//*m != mtlList[i]
			(m->defined != (mtlList[i].defined & ~MTL_HAS_GEOSTATE)) ||
			!Close_Enough(m->ambient.red, mtlList[i].ambient.red, 1e-6f) ||
			!Close_Enough(m->ambient.green, mtlList[i].ambient.green, 1e-6f) ||
			!Close_Enough(m->ambient.blue, mtlList[i].ambient.blue, 1e-6f) ||
			!Close_Enough(m->diffuse.red, mtlList[i].diffuse.red, 1e-6f) ||
			!Close_Enough(m->diffuse.green, mtlList[i].diffuse.green, 1e-6f) ||
			!Close_Enough(m->diffuse.blue, mtlList[i].diffuse.blue, 1e-6f) ||
			!Close_Enough(m->specular.red, mtlList[i].specular.red, 1e-6f) ||
			!Close_Enough(m->specular.green, mtlList[i].specular.green, 1e-6f) ||
			!Close_Enough(m->specular.blue, mtlList[i].specular.blue, 1e-6f) ||
			!Close_Enough(m->alpha, mtlList[i].alpha, 1e-6f) ||
			!Close_Enough(m->shininess, mtlList[i].shininess, 1e-6f) ||
			strcmp(m->texture, mtlList[i].texture) ||
			!Close_Enough(m->su, mtlList[i].su, 1e-6f) ||
			!Close_Enough(m->sv, mtlList[i].sv, 1e-6f) ||
			strcmp(m->reflect, mtlList[i].reflect)
		)
		{
			DEBUG_STREAM << "* Warning:  Material '" << m->name << "' in " <<
				m->library << " ignored (already defined by " << mtlList[i].library << ")" << endl;
			DEBUG_STREAM << "    " << mtlList[i].library << " " << mtlList[i].name << " " << mtlList[i].texture << endl;
			DEBUG_STREAM << "    " << m->library << " " << m->name << " " << m->texture << endl;

		}

		return;
	}
		
// grow material list 
	if (mtlListSize == 0)
	{
// create material list 
		mtlListSize = 1;
		mtlList = (objMaterial *)malloc(mtlListSize*sizeof(objMaterial));
	} else if (mtlListCount >= mtlListSize)
	{
// grow material list 
		mtlListSize *= 2;
		mtlList = (objMaterial *)realloc(mtlList, mtlListSize*sizeof(objMaterial));
	}
#ifdef        PRINT_MATERIALS_AS_PARSED
	printf("mtlListSize=%d, mtlListCount=%d, sizeof(objMaterial)=%d\n",
				mtlListSize, mtlListCount, sizeof(objMaterial));
#endif

// add material to list 
	mtlList[mtlListCount++] = *m;
}

#ifdef        FORGETFUL
static void
	forgetMaterials (void)
{
// delete list 
	if (mtlList != 0)
		pfFree(mtlList);
	mtlList = 0;
	mtlListSize = 0;
	mtlListCount = 0;
}
#endif

static void
	defineMtl (objMaterial *m)

⌨️ 快捷键说明

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