Ejemplo n.º 1
0
bool Mesh::_get(const StringName& p_name,Variant &r_ret) const {

	String sname=p_name;

	if (p_name=="morph_target/names") {

		DVector<String> sk;
		for(int i=0;i<morph_targets.size();i++)
			sk.push_back(morph_targets[i]);
		r_ret=sk;
		return true;
	} else if (p_name=="morph_target/mode") {

		r_ret = get_morph_target_mode();
		return true;
	} else if (sname.begins_with("surface_")) {

		int sl=sname.find("/");
		if (sl==-1)
			return false;
		int idx=sname.substr(8,sl-8).to_int()-1;
		String what = sname.get_slice("/",1);
		if (what=="material")
			r_ret=surface_get_material(idx);
		else if (what=="name")
			r_ret=surface_get_name(idx);
		return true;
	} else if (sname=="custom_aabb/custom_aabb") {

		r_ret=custom_aabb;
		return true;

	} else if (!sname.begins_with("surfaces"))
		return false;


	int idx=sname.get_slice("/",1).to_int();
	ERR_FAIL_INDEX_V(idx,surfaces.size(),false);

	Dictionary d;
	d["primitive"]=surface_get_primitive_type(idx);
	d["arrays"]=surface_get_arrays(idx);
	d["morph_arrays"]=surface_get_morph_arrays(idx);
	d["alphasort"]=surface_is_alpha_sorting_enabled(idx);
	Ref<Material> m = surface_get_material(idx);
	if (m.is_valid())
		d["material"]=m;
	String n = surface_get_name(idx);
	if (n!="")
		d["name"]=n;

	r_ret=d;

	return true;
}
Ejemplo n.º 2
0
bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const {

	if (_is_generated())
		return false;

	String sname = p_name;

	if (p_name == "blend_shape/names") {

		PoolVector<String> sk;
		for (int i = 0; i < blend_shapes.size(); i++)
			sk.push_back(blend_shapes[i]);
		r_ret = sk;
		return true;
	} else if (p_name == "blend_shape/mode") {

		r_ret = get_blend_shape_mode();
		return true;
	} else if (sname.begins_with("surface_")) {

		int sl = sname.find("/");
		if (sl == -1)
			return false;
		int idx = sname.substr(8, sl - 8).to_int() - 1;
		String what = sname.get_slicec('/', 1);
		if (what == "material")
			r_ret = surface_get_material(idx);
		else if (what == "name")
			r_ret = surface_get_name(idx);
		return true;
	} else if (!sname.begins_with("surfaces"))
		return false;

	int idx = sname.get_slicec('/', 1).to_int();
	ERR_FAIL_INDEX_V(idx, surfaces.size(), false);

	Dictionary d;

	d["array_data"] = VS::get_singleton()->mesh_surface_get_array(mesh, idx);
	d["vertex_count"] = VS::get_singleton()->mesh_surface_get_array_len(mesh, idx);
	d["array_index_data"] = VS::get_singleton()->mesh_surface_get_index_array(mesh, idx);
	d["index_count"] = VS::get_singleton()->mesh_surface_get_array_index_len(mesh, idx);
	d["primitive"] = VS::get_singleton()->mesh_surface_get_primitive_type(mesh, idx);
	d["format"] = VS::get_singleton()->mesh_surface_get_format(mesh, idx);
	d["aabb"] = VS::get_singleton()->mesh_surface_get_aabb(mesh, idx);

	Vector<AABB> skel_aabb = VS::get_singleton()->mesh_surface_get_skeleton_aabb(mesh, idx);
	Array arr;
	for (int i = 0; i < skel_aabb.size(); i++) {
		arr[i] = skel_aabb[i];
	}
	d["skeleton_aabb"] = arr;

	Vector<PoolVector<uint8_t> > blend_shape_data = VS::get_singleton()->mesh_surface_get_blend_shapes(mesh, idx);

	Array md;
	for (int i = 0; i < blend_shape_data.size(); i++) {
		md.push_back(blend_shape_data[i]);
	}

	d["blend_shape_data"] = md;

	Ref<Material> m = surface_get_material(idx);
	if (m.is_valid())
		d["material"] = m;
	String n = surface_get_name(idx);
	if (n != "")
		d["name"] = n;

	r_ret = d;

	return true;
}
Ejemplo n.º 3
0
Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texel_size) {

	ERR_FAIL_COND_V(!array_mesh_lightmap_unwrap_callback, ERR_UNCONFIGURED);
	ERR_EXPLAIN("Can't unwrap mesh with blend shapes");
	ERR_FAIL_COND_V(blend_shapes.size() != 0, ERR_UNAVAILABLE);

	Vector<float> vertices;
	Vector<float> normals;
	Vector<int> indices;
	Vector<int> face_materials;
	Vector<float> uv;
	Vector<Pair<int, int> > uv_index;

	Vector<ArrayMeshLightmapSurface> surfaces;
	for (int i = 0; i < get_surface_count(); i++) {
		ArrayMeshLightmapSurface s;
		s.primitive = surface_get_primitive_type(i);

		if (s.primitive != Mesh::PRIMITIVE_TRIANGLES) {
			ERR_EXPLAIN("Only triangles are supported for lightmap unwrap");
			ERR_FAIL_V(ERR_UNAVAILABLE);
		}
		s.format = surface_get_format(i);
		if (!(s.format & ARRAY_FORMAT_NORMAL)) {
			ERR_EXPLAIN("Normals are required for lightmap unwrap");
			ERR_FAIL_V(ERR_UNAVAILABLE);
		}

		Array arrays = surface_get_arrays(i);
		s.material = surface_get_material(i);
		s.vertices = SurfaceTool::create_vertex_array_from_triangle_arrays(arrays);

		PoolVector<Vector3> rvertices = arrays[Mesh::ARRAY_VERTEX];
		int vc = rvertices.size();
		PoolVector<Vector3>::Read r = rvertices.read();

		PoolVector<Vector3> rnormals = arrays[Mesh::ARRAY_NORMAL];
		PoolVector<Vector3>::Read rn = rnormals.read();

		int vertex_ofs = vertices.size() / 3;

		vertices.resize((vertex_ofs + vc) * 3);
		normals.resize((vertex_ofs + vc) * 3);
		uv_index.resize(vertex_ofs + vc);

		for (int j = 0; j < vc; j++) {

			Vector3 v = p_base_transform.xform(r[j]);
			Vector3 n = p_base_transform.basis.xform(rn[j]).normalized();

			vertices[(j + vertex_ofs) * 3 + 0] = v.x;
			vertices[(j + vertex_ofs) * 3 + 1] = v.y;
			vertices[(j + vertex_ofs) * 3 + 2] = v.z;
			normals[(j + vertex_ofs) * 3 + 0] = n.x;
			normals[(j + vertex_ofs) * 3 + 1] = n.y;
			normals[(j + vertex_ofs) * 3 + 2] = n.z;
			uv_index[j + vertex_ofs] = Pair<int, int>(i, j);
		}

		PoolVector<int> rindices = arrays[Mesh::ARRAY_INDEX];
		int ic = rindices.size();

		if (ic == 0) {

			for (int j = 0; j < vc / 3; j++) {
				if (Face3(r[j * 3 + 0], r[j * 3 + 1], r[j * 3 + 2]).is_degenerate())
					continue;

				indices.push_back(vertex_ofs + j * 3 + 0);
				indices.push_back(vertex_ofs + j * 3 + 1);
				indices.push_back(vertex_ofs + j * 3 + 2);
				face_materials.push_back(i);
			}

		} else {
			PoolVector<int>::Read ri = rindices.read();

			for (int j = 0; j < ic / 3; j++) {
				if (Face3(r[ri[j * 3 + 0]], r[ri[j * 3 + 1]], r[ri[j * 3 + 2]]).is_degenerate())
					continue;
				indices.push_back(vertex_ofs + ri[j * 3 + 0]);
				indices.push_back(vertex_ofs + ri[j * 3 + 1]);
				indices.push_back(vertex_ofs + ri[j * 3 + 2]);
				face_materials.push_back(i);
			}
		}

		surfaces.push_back(s);
	}

	//unwrap

	float *gen_uvs;
	int *gen_vertices;
	int *gen_indices;
	int gen_vertex_count;
	int gen_index_count;
	int size_x;
	int size_y;

	bool ok = array_mesh_lightmap_unwrap_callback(p_texel_size, vertices.ptr(), normals.ptr(), vertices.size() / 3, indices.ptr(), face_materials.ptr(), indices.size(), &gen_uvs, &gen_vertices, &gen_vertex_count, &gen_indices, &gen_index_count, &size_x, &size_y);

	if (!ok) {
		return ERR_CANT_CREATE;
	}

	//remove surfaces
	while (get_surface_count()) {
		surface_remove(0);
	}

	//create surfacetools for each surface..
	Vector<Ref<SurfaceTool> > surfaces_tools;

	for (int i = 0; i < surfaces.size(); i++) {
		Ref<SurfaceTool> st;
		st.instance();
		st->begin(Mesh::PRIMITIVE_TRIANGLES);
		st->set_material(surfaces[i].material);
		surfaces_tools.push_back(st); //stay there
	}

	print_line("gen indices: " + itos(gen_index_count));
	//go through all indices
	for (int i = 0; i < gen_index_count; i += 3) {

		ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], uv_index.size(), ERR_BUG);
		ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], uv_index.size(), ERR_BUG);
		ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], uv_index.size(), ERR_BUG);

		ERR_FAIL_COND_V(uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 1]]].first || uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 2]]].first, ERR_BUG);

		int surface = uv_index[gen_vertices[gen_indices[i + 0]]].first;

		for (int j = 0; j < 3; j++) {

			SurfaceTool::Vertex v = surfaces[surface].vertices[uv_index[gen_vertices[gen_indices[i + j]]].second];

			if (surfaces[surface].format & ARRAY_FORMAT_COLOR) {
				surfaces_tools[surface]->add_color(v.color);
			}
			if (surfaces[surface].format & ARRAY_FORMAT_TEX_UV) {
				surfaces_tools[surface]->add_uv(v.uv);
			}
			if (surfaces[surface].format & ARRAY_FORMAT_NORMAL) {
				surfaces_tools[surface]->add_normal(v.normal);
			}
			if (surfaces[surface].format & ARRAY_FORMAT_TANGENT) {
				Plane t;
				t.normal = v.tangent;
				t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1;
				surfaces_tools[surface]->add_tangent(t);
			}
			if (surfaces[surface].format & ARRAY_FORMAT_BONES) {
				surfaces_tools[surface]->add_bones(v.bones);
			}
			if (surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) {
				surfaces_tools[surface]->add_weights(v.weights);
			}

			Vector2 uv2(gen_uvs[gen_indices[i + j] * 2 + 0], gen_uvs[gen_indices[i + j] * 2 + 1]);
			surfaces_tools[surface]->add_uv2(uv2);

			surfaces_tools[surface]->add_vertex(v.vertex);
		}
	}

	//free stuff
	::free(gen_vertices);
	::free(gen_indices);
	::free(gen_uvs);

	//generate surfaces

	for (int i = 0; i < surfaces_tools.size(); i++) {
		surfaces_tools[i]->index();
		surfaces_tools[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), surfaces[i].format);
	}

	set_lightmap_size_hint(Size2(size_x, size_y));

	return OK;
}