C++读入obj格式模型文件

#ifndef  _LOADOBJ_H_
#define  _LOADOBJ_H_

#include <math.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

#define dot(u,v)   ((u).x * (v).x + (u).y * (v).y + (u).z*(v).z)  
#define norm2(v)   dot(v,v)        // norm2 = squared length of vector  
#define norm(v)    sqrt(norm2(v))  // norm = length of vector  
#define d(u,v)     norm(u-v)       // distance = norm of difference  

// Obj loader
struct TriangleFace 
{
	int v[3]; // vertex indices
};

class float3
{
public:	
	float x;
	float y;
	float z;
public:	
	float3(){x=0;y=0;z=0;}
	float3(float mx,float my,float mz){x=mx;y=my;z=mz;}
	~float3(){}

	float3 operator+(float3);
	float3 operator-(float3);
	float3 operator/(float);

	friend float3 operator*(float m,float3 f3)
	{
		return float3(f3.x*m,f3.y*m,f3.z*m);
	}
	friend float3 operator*(float3 f3,float m)
	{
		return float3(f3.x*m,f3.y*m,f3.z*m);
	}

	float3 operator=(float3);

	float3& operator += (float3);
	
};

float3 float3::operator +(float3 m)
{
	float3 result;
	result.x = x+m.x;
	result.y = y+m.y;
	result.z = z+m.z;
	return result;
}

float3 float3::operator - (float3 m)
{
	float3 result;
	result.x = x-m.x;
	result.y = y-m.y;
	result.z = z-m.z;
	return result;
}

float3 float3::operator /(float m)
{
	if(m==0){
		printf("error /");
		return float3(x,y,z);
	}
	else
		return float3(x/m,y/m,z/m);
}

float3 float3::operator =(float3 f3)
{
	x = f3.x;
	y = f3.y;
	z = f3.z;
	return float3(x,y,z);
}

struct TriangleMesh
{
	vector<float3> verts;
	vector<TriangleFace> faces;
	//模型的包围盒
	float3 bounding_box[2];
	//模型的包围球参数
	float3 bounding_sphere_c;
	float bounding_sphere_r;
};

TriangleMesh mesh;

int total_number_of_triangles = 0;

// Scene bounding box 
float3 scene_aabbox_min;
float3 scene_aabbox_max;

void loadObj(const std::string filename, TriangleMesh &mesh);

void loadObj( const std::string filename, TriangleMesh &mesh )
{
	std::ifstream in(filename.c_str());

	if(!in.good())
	{
		cout  << "ERROR: loading obj:(" << filename << ") file is not good" << "\n";
		exit(0);
	}

	char buffer[256], str[255];
	float f1,f2,f3;
	
	while(!in.getline(buffer,255).eof())
	{
		buffer[255]='\0';

		sscanf_s(buffer,"%s",str,255);

		// reading a vertex
		if (buffer[0]=='v' && (buffer[1]==' '  || buffer[1]==32) )
		{
			if ( sscanf(buffer,"v %f %f %f",&f1,&f2,&f3)==3)
			{
				mesh.verts.push_back(float3(f1,f2,f3));
			}
			else
			{
				cout << "ERROR: vertex not in wanted format in OBJLoader" << "\n";
				exit(-1);
			}
		}
		// reading FaceMtls 
		else if (buffer[0]=='f' && (buffer[1]==' ' || buffer[1]==32) )
		{
			TriangleFace f;
			int nt = sscanf(buffer,"f %d %d %d",&f.v[0],&f.v[1],&f.v[2]);
			if( nt!=3 )
			{
				cout << "ERROR: I don't know the format of that FaceMtl" << "\n";
				exit(-1);
			}

			mesh.faces.push_back(f);
		}
	}
	
	float xmin,ymin,zmin,xmax,ymax,zmax;
	int Pxmin,Pxmax,Pymin,Pymax,Pzmin,Pzmax;
	
	//calculate the bounding sphere
	xmin = xmax = mesh.verts[0].x;
	ymin = ymax = mesh.verts[0].y;
	zmin = zmax = mesh.verts[0].z;
	Pxmin = Pxmax = Pymin = Pymax = Pzmin = Pzmax = 0;

	//calculate the bounding box
	mesh.bounding_box[0] = float3(mesh.verts[0].x,mesh.verts[0].y,mesh.verts[0].z);
	mesh.bounding_box[1] = float3(mesh.verts[0].x,mesh.verts[0].y,mesh.verts[0].z);

	for(unsigned int i = 1; i < mesh.verts.size(); i++)
	{
		//update min value
		mesh.bounding_box[0].x = min(mesh.verts[i].x,mesh.bounding_box[0].x);
		mesh.bounding_box[0].y = min(mesh.verts[i].y,mesh.bounding_box[0].y);
		mesh.bounding_box[0].z = min(mesh.verts[i].z,mesh.bounding_box[0].z);

		//update max value
		mesh.bounding_box[1].x = max(mesh.verts[i].x,mesh.bounding_box[1].x);
		mesh.bounding_box[1].y = max(mesh.verts[i].y,mesh.bounding_box[1].y);
		mesh.bounding_box[1].z = max(mesh.verts[i].z,mesh.bounding_box[1].z);

		//update the  x min and max
		if (mesh.verts[i].x < xmin){
			xmin = mesh.verts[i].x;
			Pxmin = i;
		}
		else if(mesh.verts[i].x > xmax){
			xmax = mesh.verts[i].x;
			Pxmax = i;
		}
		//update the y min and max
		if (mesh.verts[i].y < ymin){
			ymin = mesh.verts[i].y;
			Pymin = i;
		}
		else if(mesh.verts[i].y > ymax){
			ymax = mesh.verts[i].y;
			Pymax = i;
		}
		//update the z min and max
		if(mesh.verts[i].z < zmin){
			zmin = mesh.verts[i].z;
			Pzmin = i;
		}
		else if(mesh.verts[i].z > zmax){
			zmax = mesh.verts[i].z;
			Pzmax = i;
		}
	}
	
	//calculate the bounding sphere
	float3 dVx = mesh.verts[Pxmax] - mesh.verts[Pxmin];
	float3 dVy = mesh.verts[Pymax] - mesh.verts[Pymin];
	float3 dVz = mesh.verts[Pzmax] - mesh.verts[Pzmin];
	float dx2 = norm2(dVx);
	float dy2 = norm2(dVy);
	float dz2 = norm2(dVz);

	float3 center;
	float  radius2;
	float  radius;

	if (dx2 >= dy2 && dx2>=dz2) {					// x direction is largest extent  
		center = mesh.verts[Pxmin] + (dVx / 2.0);	// Center = midpoint of extremes  
		radius2 = norm2(mesh.verts[Pxmax] - center);// radius squared  
	}  
	else if (dy2 >= dx2  && dy2>=dz2){				// y direction is largest extent  
		center = mesh.verts[Pymin] + (dVy / 2.0);	// Center = midpoint of extremes  
		radius2 = norm2(mesh.verts[Pymax] - center);// radius squared  
	} 
	else{
		center = mesh.verts[Pzmin] + (dVz / 2.0);	// Center = midpoint of extremes  
		radius2 = norm2(mesh.verts[Pzmax] - center);// radius squared  	
	}

	radius = sqrt(radius2);  

	// now check that all points V[i] are in the ball  
	// and if not, expand the ball just enough to include them  
	float3 dV;
	float dist2,dist;
	for (unsigned int i=0;i<mesh.verts.size();i++)
	{
		dV = mesh.verts[i] - center;
		dist2 = norm2(dV);
		if (dist2 <= radius2) // V[i] is inside the ball already  
			continue;

		// V[i] not in ball, so expand ball to include it  
		dist = sqrt(dist2);  
		radius = (radius + dist) / 2.0;         // enlarge radius just enough  
		radius2 = radius * radius;  
		center = center + ((dist-radius)/dist) * dV;   // shift Center toward V[i]  
		
	}
	
	mesh.bounding_sphere_c = center;
	mesh.bounding_sphere_r = radius;
	
	cout<< "----------obj file loaded-------------"<<endl;
	cout<<"number of faces:" << mesh.faces.size() << " number of vertices:" << mesh.verts.size() << endl;
	cout<< "obj bounding box: min:(" 
		<< mesh.bounding_box[0].x << "," << mesh.bounding_box[0].y << "," << mesh.bounding_box[0].z <<") max:(" 
		<< mesh.bounding_box[1].x << "," << mesh.bounding_box[1].y << "," << mesh.bounding_box[1].z <<")" << endl
		<<"obj bounding sphere center:"<<mesh.bounding_sphere_c.x<<","<<mesh.bounding_sphere_c.y<<","<<mesh.bounding_sphere_c.z<<endl
		<<"obj bounding sphere radius:"<<mesh.bounding_sphere_r<<endl;

}


#endif

用法:


#include "LoadObj.h"

void main()
{
	std::string filename = "E:\\codeLab\\cube.obj";
	
	TriangleMesh mesh;

	loadObj(filename, mesh);
}


注意:请使用英文目录。



  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
### 回答1: C语言是一种高级编程语言,它经过编译后会生成机器可读的目标代码,通常是二进制文件。因此,C语言的反编译就是将这些二进制文件转换回可读的源代码。 C语言的反编译工具主要通过分析目标代码和逆向工程技术来实现。这些工具可以读取目标文件中的二进制指令,并尝试还原出原始的C语言源代码。 然而,C语言的反编译并不是完全准确和可逆的过程。由于编译器的优化等因素,一些信息在编译后就会丢失,使得反编译后的代码可能存在一些差异和不完全性。此外,由于反编译工具的算法和原始代码的复杂性,反编译结果可能会比较难以理解和修改。 尽管如此,C语言的反编译仍然被广泛用于软件逆向工程、恶意代码分析和漏洞研究等领域。通过反编译,我们可以深入了解程序的执行流程、数据结构和算法逻辑,为后续分析和修改提供了便利。 总结来说,C语言反编译是将编译后的目标代码转换为可读的源代码的过程。虽然反编译结果可能不完全准确,但它在软件逆向工程和漏洞研究等领域具有重要的应用价值。 ### 回答2: C语言中的反编译是指将已编译的对象文件(.obj)转化为可读的源代码的过程。反编译是一种逆向工程的技术,它可以帮助开发者了解和分析已编译的程序,以及进行程序的修改和优化。 要进行C语言的反编译,需要使用专业的反汇编工具。常用的反汇编工具有IDA Pro、OllyDbg等。这些工具可以将机器语言指令逆向还原为汇编语言代码,从而辅助开发者理解源代码的结构和逻辑。 反编译过程中,开发者需要仔细研究汇编代码,通过对指令的分析、跳转和数据交互等操作的观察,来推测原始C语言源代码的结构和功能。这个过程需要一定的经验和技巧,同时也需要对C语言的编译原理和汇编语言有深入的了解。 但需要注意的是,反编译并不意味着完全还原原始的C代码。由于编译过程中存在优化和信息丢失的情况,反编译后的代码可能会有一定的差异,并且可能存在一些不确定性。因此,反编译得到的代码一般需要经过进一步的修复和调试,以便使其在编译时能够正常通过。 总的来说,C语言的反编译是一项复杂而有挑战的工作,它需要一定的专业工具和技术支持,并且对反汇编和C编程有较深的了解。通过反编译,可以帮助开发者了解、分析和修改已编译的程序,提升开发效率和代码质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值