示例#1
0
Curve *load_curve(const char *fname) {
	FILE *fp = fopen(fname, "r");
	if(!fp) {
		error("failed to open file %s", fname);
		return 0;
	}

	char buffer[256];

	fgets(buffer, 256, fp);
	if(strcmp(buffer, "curve_3dengfx\n") != 0) {
		error("load_curve failed, %s is not a curve file", fname);
		fclose(fp);
		return 0;
	}

	Curve *curve;

	fgets(buffer, 256, fp);
	std::string name = buffer;

	fgets(buffer, 256, fp);
	if(!strcmp(buffer, "bspline\n")) {
		curve = new BSpline;
	} else if(!strcmp(buffer, "catmullrom\n")) {
		curve = new CatmullRomSpline;
	} else /*if(!strcmp(buffer, "bezier"))*/ {
		error("unsupported curve type (%s) or not a curve file", buffer);
		fclose(fp);
		return 0;
	}

	curve->name = name;

	fgets(buffer, 256, fp);
	if(!isdigit(buffer[0])) {
		error("load_curve failed, %s is not a valid curve file (count: %s)", fname, buffer);
		delete curve;
		fclose(fp);
		return 0;
	}
	int count = atoi(buffer);

	int failed = count;
	for(int i=0; i<count; i++, failed--) {
		fgets(buffer, 256, fp);
		if(!isdigit(buffer[0]) && buffer[0] != '.' && buffer[0] != '-') {
			break;
		}
		float x = atof(buffer);

		char *ptr = strchr(buffer, ' ');
		if(!ptr || (!isdigit(ptr[1]) && ptr[1] != '.' && ptr[1] != '-')) {
			break;
		}
		float y = atof(++ptr);
		
		ptr = strchr(ptr, ' ');
		if(!ptr || (!isdigit(ptr[1]) && ptr[1] != '.' && ptr[1] != '-')) {
			break;
		}
		float z = atof(++ptr);

		curve->add_control_point(Vector3(x, y, z));
	}

	fclose(fp);

	if(failed) {
		error("load_curve failed to read the data, %s is not a valid curve file", fname);
		delete curve;
		return 0;
	}

	return curve;
}
static bool load_objects(Lib3dsFile *file, Scene *scene) {
	// load meshes
	unsigned long poly_count = 0;
	Lib3dsMesh *m = file->meshes;
	while(m) {

		Lib3dsNode *node = lib3ds_file_node_by_name(file, m->name, LIB3DS_OBJECT_NODE);
		if(!node) {
			warning("object \"%s\" does not have a corresponding node!", m->name);
		}
		Vector3 node_pos = node ? CONV_VEC3(node->data.object.pos) : Vector3();
		Quaternion node_rot = node ? CONV_QUAT(node->data.object.rot) : Quaternion();
		Vector3 node_scl = node ? CONV_VEC3(node->data.object.scl) : Vector3(1,1,1);
		Vector3 pivot = node ? CONV_VEC3(node->data.object.pivot) : Vector3();

		// load the vertices
		Vertex *varray = new Vertex[m->points];
		Vertex *vptr = varray;
		for(int i=0; i<(int)m->points; i++) {
			vptr->pos = CONV_VEC3(m->pointL[i].pos) - node_pos;
			vptr->pos.transform(node_rot);
			
			if(m->texels) {
				vptr->tex[0] = vptr->tex[1] = CONV_TEXCOORD(m->texelL[i]);
			}
			
			vptr++;
		}
		
		if(m->faces) {
			poly_count += m->faces;
			// -------- object ---------
			Object *obj = new Object;
			obj->set_dynamic(false);

			obj->name = m->name;

			obj->set_position(node_pos - pivot);
			obj->set_rotation(node_rot);
			obj->set_scaling(node_scl);

			obj->set_pivot(pivot);
		
			// load the polygons
			Triangle *tarray = new Triangle[m->faces];
			Triangle *tptr = tarray;
			for(int i=0; i<(int)m->faces; i++) {
				*tptr = CONV_TRIANGLE(m->faceL[i]);
				tptr->normal = CONV_VEC3(m->faceL[i].normal);
				tptr->smoothing_group = m->faceL[i].smoothing;

				tptr++;
			}

			// set the geometry data to the object
			obj->get_mesh_ptr()->set_data(varray, m->points, tarray, m->faces);
			obj->get_mesh_ptr()->calculate_normals();
		
			delete [] tarray;

			// load the material
			load_material(file, m->faceL[0].material, obj->get_material_ptr());

			// load the keyframes (if any)
			if(load_keyframes(file, m->name, LIB3DS_OBJECT_NODE, obj)) {
				obj->set_position(Vector3());
				obj->set_rotation(Quaternion());
				obj->set_scaling(Vector3(1, 1, 1));
			}

			scene->add_object(obj);
			
		} else {
			// --------- curve ------------
			Curve *curve = new CatmullRomSplineCurve;
			curve->name = m->name;

			Vector3 offs = node_pos - pivot;
			
			for(int i=0; i<(int)m->points; i++) {
				curve->add_control_point(varray[i].pos + offs);
			}

			scene->add_curve(curve);
		}

		delete [] varray;


		m = m->next;
	}
	
	scene->set_poly_count(poly_count);
	return true;
}