Esempio n. 1
0
void GIProbe::_find_meshes(Node *p_at_node,Baker *p_baker){

	MeshInstance *mi = p_at_node->cast_to<MeshInstance>();
	if (mi && mi->get_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT)) {
		Ref<Mesh> mesh = mi->get_mesh();
		if (mesh.is_valid()) {

			Rect3 aabb = mesh->get_aabb();

			Transform xf = get_global_transform().affine_inverse() * mi->get_global_transform();

			if (Rect3(-extents,extents*2).intersects(xf.xform(aabb))) {
				Baker::PlotMesh pm;
				pm.local_xform=xf;
				pm.mesh=mesh;
				p_baker->mesh_list.push_back(pm);

			}
		}
	}

	for(int i=0;i<p_at_node->get_child_count();i++) {

		Node *child = p_at_node->get_child(i);
		if (!child->get_owner())
			continue; //maybe a helper

		_find_meshes(child,p_baker);

	}
}
Esempio n. 2
0
Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {

	List<Ref<Mesh> > meshes;

	Error err = _parse_obj(p_path, meshes, false, p_flags & IMPORT_GENERATE_TANGENT_ARRAYS, Vector3(1, 1, 1), r_missing_deps);

	if (err != OK) {
		if (r_err) {
			*r_err = err;
		}
		return NULL;
	}

	Spatial *scene = memnew(Spatial);

	for (List<Ref<Mesh> >::Element *E = meshes.front(); E; E = E->next()) {

		MeshInstance *mi = memnew(MeshInstance);
		mi->set_mesh(E->get());
		mi->set_name(E->get()->get_name());
		scene->add_child(mi);
		mi->set_owner(scene);
	}

	if (r_err) {
		*r_err = OK;
	}

	return scene;
}
void MeshInstanceEditor::_create_outline_mesh() {

    Ref<Mesh> mesh = node->get_mesh();
    if (mesh.is_null()) {
        err_dialog->set_text(TTR("MeshInstance lacks a Mesh!"));
        err_dialog->popup_centered_minsize();
        return;
    }

    Ref<Mesh> mesho = mesh->create_outline(outline_size->get_val());

    if (mesho.is_null()) {
        err_dialog->set_text(TTR("Could not create outline!"));
        err_dialog->popup_centered_minsize();
        return;
    }

    MeshInstance *mi = memnew( MeshInstance );
    mi->set_mesh(mesho);
    Node *owner=node->get_owner();
    if (get_tree()->get_edited_scene_root()==node) {
        owner=node;
    }

    UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();

    ur->create_action(TTR("Create Outline"));

    ur->add_do_method(node,"add_child",mi);
    ur->add_do_method(mi,"set_owner",owner);

    ur->add_do_reference(mi);
    ur->add_undo_method(node,"remove_child",mi);
    ur->commit_action();
}
Esempio n. 4
0
void NavigationMeshInstance::_notification(int p_what) {

	switch (p_what) {
		case NOTIFICATION_ENTER_TREE: {

			Spatial *c = this;
			while (c) {

				navigation = c->cast_to<Navigation>();
				if (navigation) {

					if (enabled && navmesh.is_valid()) {

						nav_id = navigation->navmesh_create(navmesh, get_relative_transform(navigation), this);
					}
					break;
				}

				c = c->get_parent_spatial();
			}

			if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) {

				MeshInstance *dm = memnew(MeshInstance);
				dm->set_mesh(navmesh->get_debug_mesh());
				if (is_enabled()) {
					dm->set_material_override(get_tree()->get_debug_navigation_material());
				} else {
					dm->set_material_override(get_tree()->get_debug_navigation_disabled_material());
				}
				add_child(dm);
				debug_view = dm;
			}

		} break;
		case NOTIFICATION_TRANSFORM_CHANGED: {

			if (navigation && nav_id != -1) {
				navigation->navmesh_set_transform(nav_id, get_relative_transform(navigation));
			}

		} break;
		case NOTIFICATION_EXIT_TREE: {

			if (navigation) {

				if (nav_id != -1) {
					navigation->navmesh_remove(nav_id);
					nav_id = -1;
				}
			}

			if (debug_view) {
				debug_view->queue_delete();
				debug_view = NULL;
			}
			navigation = NULL;
		} break;
	}
}
////////////////////////////////////////////////////////////////////////////////
// SoftShadowsRenderer::getSceneStats()
////////////////////////////////////////////////////////////////////////////////
void SoftShadowsRenderer::getSceneStats(uint64_t &numIndices, uint64_t &numVertices, uint32_t &lightResolution) const
{
    numIndices = 0;
    numVertices = 0;
    lightResolution = LIGHT_RES;

    for (MeshInstanceList::const_iterator it = m_meshInstances.begin(); it != m_meshInstances.end(); ++it)
    {
        MeshInstance *instance = *it;
        instance->accumStats(numIndices, numVertices);
    }
}
////////////////////////////////////////////////////////////////////////////////
// SoftShadowsRenderer::drawMeshes()
////////////////////////////////////////////////////////////////////////////////
void SoftShadowsRenderer::drawMeshes(SceneShader &shader)
{
    shader.setUseDiffuse(true);
    for (MeshInstanceList::iterator it = m_meshInstances.begin(); it != m_meshInstances.end(); ++it)
    {
        MeshInstance *instance = *it;
        if (instance == m_podiumMesh)
            shader.setUseTexture(m_useTexture ? 2 : 0);
        else
            shader.setUseTexture(0);

        instance->draw(shader);
    }
}
void ClientGameObjectManagerAddon::createSpaceShip(int &threadOwnershipMask)
{

	//create hierarchy:
	//scene root
	//  scene node // tracks position/orientation
	//    SpaceShip

	//game object manager
	//  SpaceShipController
	//    scene node

	PE::Handle hMeshInstance("MeshInstance", sizeof(MeshInstance));
	MeshInstance *pMeshInstance = new(hMeshInstance) MeshInstance(*m_pContext, m_arena, hMeshInstance);

	pMeshInstance->addDefaultComponents();
	pMeshInstance->initFromFile("space_frigate_6.mesha", "FregateTest", threadOwnershipMask);

	// need to create a scene node for this mesh
	PE::Handle hSN("SCENE_NODE", sizeof(SceneNode));
	SceneNode *pSN = new(hSN) SceneNode(*m_pContext, m_arena, hSN);
	pSN->addDefaultComponents();

	Vector3 spawnPos(0, 0, 0.0f);
	pSN->m_base.setPos(spawnPos);

	pSN->addComponent(hMeshInstance);

	RootSceneNode::Instance()->addComponent(hSN);

	// now add game objects

	PE::Handle hSpaceShip("ClientSpaceShip", sizeof(ClientSpaceShip));
	ClientSpaceShip *pSpaceShip = new(hSpaceShip) ClientSpaceShip(*m_pContext, m_arena, hSpaceShip, 0.05f, spawnPos,  0.05f);
	pSpaceShip->addDefaultComponents();

	addComponent(hSpaceShip);

	// add the same scene node to tank controller
	static int alllowedEventsToPropagate[] = {0}; // we will pass empty array as allowed events to propagate so that when we add
	// scene node to the square controller, the square controller doesnt try to handle scene node's events
	// because scene node handles events through scene graph, and is child of space ship just for referencing purposes
	pSpaceShip->addComponent(hSN, &alllowedEventsToPropagate[0]);

	pSpaceShip->activate();
}
Esempio n. 8
0
void CollisionShape::_update_debug_shape() {
	debug_shape_dirty = false;

	if (debug_shape) {
		debug_shape->queue_delete();
		debug_shape = NULL;
	}

	Ref<Shape> s = get_shape();
	if (s.is_null())
		return;

	Ref<Mesh> mesh = s->get_debug_mesh();
	MeshInstance *mi = memnew(MeshInstance);
	mi->set_mesh(mesh);
	add_child(mi);
	debug_shape = mi;
}
void ClientGameObjectManagerAddon::createTank(int index, int &threadOwnershipMask)
{

	//create hierarchy:
	//scene root
	//  scene node // tracks position/orientation
	//    Tank

	//game object manager
	//  TankController
	//    scene node
	
	PE::Handle hMeshInstance("MeshInstance", sizeof(MeshInstance));
	MeshInstance *pMeshInstance = new(hMeshInstance) MeshInstance(*m_pContext, m_arena, hMeshInstance);

	pMeshInstance->addDefaultComponents();
	pMeshInstance->initFromFile("kingtiger.x_main_mesh.mesha", "Default", threadOwnershipMask);

	// need to create a scene node for this mesh
	PE::Handle hSN("SCENE_NODE", sizeof(SceneNode));
	SceneNode *pSN = new(hSN) SceneNode(*m_pContext, m_arena, hSN);
	pSN->addDefaultComponents();

	Vector3 spawnPos(-36.0f + 6.0f * index, 0 , 21.0f);
	pSN->m_base.setPos(spawnPos);
	
	pSN->addComponent(hMeshInstance);

	RootSceneNode::Instance()->addComponent(hSN);

	// now add game objects

	PE::Handle hTankController("TankController", sizeof(TankController));
	TankController *pTankController = new(hTankController) TankController(*m_pContext, m_arena, hTankController, 0.05f, spawnPos,  0.05f);
	pTankController->addDefaultComponents();

	addComponent(hTankController);

	// add the same scene node to tank controller
	static int alllowedEventsToPropagate[] = {0}; // we will pass empty array as allowed events to propagate so that when we add
	// scene node to the square controller, the square controller doesnt try to handle scene node's events
	// because scene node handles events through scene graph, and is child of square controller just for referencing purposes
	pTankController->addComponent(hSN, &alllowedEventsToPropagate[0]);
}
Esempio n. 10
0
void CollisionShape::make_convex_from_brothers() {

	Node *p = get_parent();
	if (!p)
		return;

	for (int i = 0; i < p->get_child_count(); i++) {

		Node *n = p->get_child(i);
		MeshInstance *mi = Object::cast_to<MeshInstance>(n);
		if (mi) {

			Ref<Mesh> m = mi->get_mesh();
			if (m.is_valid()) {

				Ref<Shape> s = m->create_convex_shape();
				set_shape(s);
			}
		}
	}
}
Esempio n. 11
0
void HRMEMainWindow::setSelectedObject(MapObject* selected_object) {

	positionPropertyFrame->setEnabled(false);
	rotationPropertyFrame->setEnabled(false);
	scalePropertyFrame->setEnabled(false);
	colorPropertyFrame->setEnabled(false);
	attenuationPropertyFrame->setEnabled(false);
	meshInstancePropertyFrame->setEnabled(false);

	Light* light;
	MeshInstance* instance;

	if (selected_object) {
		switch (selected_object->getType()) {
			case MapObject::LIGHT:
				light = ((LightObject*)selected_object)->getLight();
				lightStrengthBox->setValue(light->getStrength());
				lightAttenuationBox->setChecked(light->getHasAttenuation());
				attenuationPropertyFrame->setEnabled(true);
				break;

			case MapObject::MESH_INSTANCE:
				instance = ((MeshInstanceObject*)selected_object)->getMeshInstance();
				meshInstancePropertyFrame->setEnabled(true);
				instanceTypeBox->setCurrentIndex(static_cast<int>(instance->getType()));
				;break;

			default:
				break;
		}
		positionPropertyFrame->setEnabled(true);
		colorPropertyFrame->setEnabled(selected_object->hasColors());
		rotationPropertyFrame->setEnabled(selected_object->hasRotation());
		scalePropertyFrame->setEnabled(selected_object->hasScale());
	}

	for (int i = 0; i < objectPropertyWidgets.size(); i++) {
		objectPropertyWidgets.at(i)->setVisible(objectPropertyWidgets.at(i)->parentWidget()->isEnabled());
	}
}
Esempio n. 12
0
void NavigationMeshInstance::set_enabled(bool p_enabled) {

	if (enabled == p_enabled)
		return;
	enabled = p_enabled;

	if (!is_inside_tree())
		return;

	if (!enabled) {

		if (nav_id != -1) {
			navigation->navmesh_remove(nav_id);
			nav_id = -1;
		}
	} else {

		if (navigation) {

			if (navmesh.is_valid()) {

				nav_id = navigation->navmesh_create(navmesh, get_relative_transform(navigation), this);
			}
		}
	}

	if (debug_view) {
		MeshInstance *dm = debug_view->cast_to<MeshInstance>();
		if (is_enabled()) {
			dm->set_material_override(get_tree()->get_debug_navigation_material());
		} else {
			dm->set_material_override(get_tree()->get_debug_navigation_disabled_material());
		}
	}

	update_gizmo();
}
Esempio n. 13
0
void MeshInstance::create_debug_tangents() {

	Vector<Vector3> lines;
	Vector<Color> colors;

	Ref<Mesh> mesh = get_mesh();
	if (!mesh.is_valid())
		return;

	for (int i = 0; i < mesh->get_surface_count(); i++) {
		Array arrays = mesh->surface_get_arrays(i);
		Vector<Vector3> verts = arrays[Mesh::ARRAY_VERTEX];
		Vector<Vector3> norms = arrays[Mesh::ARRAY_NORMAL];
		if (norms.size() == 0)
			continue;
		Vector<float> tangents = arrays[Mesh::ARRAY_TANGENT];
		if (tangents.size() == 0)
			continue;

		for (int j = 0; j < verts.size(); j++) {
			Vector3 v = verts[j];
			Vector3 n = norms[j];
			Vector3 t = Vector3(tangents[j * 4 + 0], tangents[j * 4 + 1], tangents[j * 4 + 2]);
			Vector3 b = (n.cross(t)).normalized() * tangents[j * 4 + 3];

			lines.push_back(v); //normal
			colors.push_back(Color(0, 0, 1)); //color
			lines.push_back(v + n * 0.04); //normal
			colors.push_back(Color(0, 0, 1)); //color

			lines.push_back(v); //tangent
			colors.push_back(Color(1, 0, 0)); //color
			lines.push_back(v + t * 0.04); //tangent
			colors.push_back(Color(1, 0, 0)); //color

			lines.push_back(v); //binormal
			colors.push_back(Color(0, 1, 0)); //color
			lines.push_back(v + b * 0.04); //binormal
			colors.push_back(Color(0, 1, 0)); //color
		}
	}

	if (lines.size()) {

		Ref<SpatialMaterial> sm;
		sm.instance();

		sm->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
		sm->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
		sm->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);

		Ref<ArrayMesh> am;
		am.instance();
		Array a;
		a.resize(Mesh::ARRAY_MAX);
		a[Mesh::ARRAY_VERTEX] = lines;
		a[Mesh::ARRAY_COLOR] = colors;

		am->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a);
		am->surface_set_material(0, sm);

		MeshInstance *mi = memnew(MeshInstance);
		mi->set_mesh(am);
		mi->set_name("DebugTangents");
		add_child(mi);
#ifdef TOOLS_ENABLED

		if (this == get_tree()->get_edited_scene_root())
			mi->set_owner(this);
		else
			mi->set_owner(get_owner());
#endif
	}
}
Esempio n. 14
0
Flyer::Flyer(PE::GameContext &context, PE::MemoryArena arena, PE::Handle hMyself, int &threadOwnershipMask) 
: Component(context, arena, hMyself)
, m_prevCameraType(CameraManager::CameraType_Count)
{
	// NUI testing
#ifdef _XBOX
	// Could also try for a bit more smoothing ( 0.25f, 0.25f, 0.25f, 0.03f, 0.05f );
	m_JointFilter.Init( 0.5f, 0.5f, 0.5f, 0.05f, 0.05f );

	// create event which will be signaled when frame processing ends
	m_hFrameEndEvent = CreateEvent( NULL,
		FALSE,  // auto-reset
		FALSE,  // create unsignaled
		"NuiFrameEndEvent" );

	if ( !m_hFrameEndEvent )
	{
		ATG_PrintError( "Failed to create NuiFrameEndEvent\n" );
		return;
		// return E_FAIL;
	}

	HRESULT hr = NuiInitialize( NUI_INITIALIZE_FLAG_USES_SKELETON |
		NUI_INITIALIZE_FLAG_USES_COLOR |
		NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX,
		NUI_INITIALIZE_DEFAULT_HARDWARE_THREAD );

	if( FAILED( hr ))
	{
		ATG::NuiPrintError( hr, "NuiInitialize" );
		return;
		// return E_FAIL;
	}
	
	// register frame end event with NUI
	hr = NuiSetFrameEndEvent( m_hFrameEndEvent, 0 );
	if( FAILED(hr) )
	{
		ATG::NuiPrintError( hr, "NuiSetFrameEndEvent" );
		return;
		// return E_FAIL;
	}

	/*
	// Open the color stream
	hr = NuiImageStreamOpen( NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_640x480, 0, 1, NULL, &m_hImage );
	if( FAILED (hr) )
	{
		ATG::NuiPrintError( hr, "NuiImageStreamOpen" );
		return E_FAIL;
	}

	// Open the depth stream
	hr = NuiImageStreamOpen( NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX, NUI_IMAGE_RESOLUTION_320x240, 0, 1, NULL, &m_hDepth );
	if( FAILED (hr) )
	{
		ATG::NuiPrintError( hr, "NuiImageStreamOpen" );
		return E_FAIL;
	}
	*/
	hr = NuiSkeletonTrackingEnable( NULL, 0 );
	if( FAILED( hr ))
	{
		ATG::NuiPrintError( hr, "NuiSkeletonTrackingEnable" );
	}

	m_pNuiJointConverterConstrained = new ATG::NuiJointConverter();
	if( m_pNuiJointConverterConstrained == NULL )
	{
		// return E_FAIL;
		return;
	}

	m_pNuiJointConverterConstrained->AddDefaultConstraints();
	
	Handle hSN("SceneNode", sizeof(SceneNode));
	m_pNuiSN = new(hSN) SceneNode(context, arena, hSN);
	m_pNuiSN->addDefaultComponents();
	m_pNuiSN->m_base.setPos(Vector3(0.0f, 0, 25.0f));
	m_pNuiSN->m_base.turnRight(1.2f * 3.1415f);
	RootSceneNode::Instance()->addComponent(hSN);
	for (int i = 0; i < XAVATAR_MAX_SKELETON_JOINTS; i++)
	{
		PE::Handle hMeshInstance("MeshInstance", sizeof(MeshInstance));
		MeshInstance *pMeshInstance = new(hMeshInstance) MeshInstance(*m_pContext, m_arena, hMeshInstance);
		pMeshInstance->addDefaultComponents();

		pMeshInstance->initFromFile("box.x_main_mesh.mesha", "Default", threadOwnershipMask);
		
		Handle hSN("SceneNode", sizeof(SceneNode));
		m_sceneNodes[i] = new(hSN) SceneNode(context, arena, hSN);
		m_sceneNodes[i]->addDefaultComponents();
		m_sceneNodes[i]->addComponent(hMeshInstance);
		m_pNuiSN->addComponent(hSN);

		if (m_pNuiJointConverterConstrained->MapAvatarJointToNUI_POSITION_INDEX(i) == NUI_SKELETON_POSITION_SHOULDER_RIGHT)
		{
			PE::Handle hMeshInstance("MeshInstance", sizeof(MeshInstance));
			MeshInstance *pMeshInstance = new(hMeshInstance) MeshInstance(*m_pContext, m_arena, hMeshInstance);
			pMeshInstance->addDefaultComponents();
			pMeshInstance->initFromFile("wings.x_rwing_mesh.mesha", "City", threadOwnershipMask);
			
			m_sceneNodes[i]->addComponent(hMeshInstance);
		}

		if (m_pNuiJointConverterConstrained->MapAvatarJointToNUI_POSITION_INDEX(i) == NUI_SKELETON_POSITION_SHOULDER_LEFT)
		{
			
			PE::Handle hMeshInstance("MeshInstance", sizeof(MeshInstance));
			MeshInstance *pMeshInstance = new(hMeshInstance) MeshInstance(*m_pContext, m_arena, hMeshInstance);

			pMeshInstance->addDefaultComponents();
			pMeshInstance->initFromFile("wings.x_lwing_mesh.mesha", "City", threadOwnershipMask);

			m_sceneNodes[i]->addComponent(hMeshInstance);
		}
	}
	{
			// put a camera here

		PE::Handle hMeshInstance("MeshInstance", sizeof(MeshInstance));
		MeshInstance *pMeshInstance = new(hMeshInstance) MeshInstance(*m_pContext, m_arena, hMeshInstance);

		pMeshInstance->addDefaultComponents();
		pMeshInstance->initFromFile("box.x_main_mesh.mesha", "Default", threadOwnershipMask);

		// we put camera in a scene node so we can rotate the camera within that scene node, but we could have also just added camera on its own
		Handle hSN("SceneNode", sizeof(SceneNode));
		m_pCamSN = new(hSN) SceneNode(context, arena,hSN);
		m_pCamSN->addDefaultComponents();
		m_pCamSN->addComponent(hMeshInstance);
		m_pNuiSN->addComponent(hSN);
		m_pCamSN->m_base.setPos(Vector3(0, +1.0f, +1.5f));

		Handle hDebugCamera("Camera", sizeof(Camera));
		Camera *debugCamera = new(hDebugCamera) Camera(context, arena, hDebugCamera, hSN);
		debugCamera->addDefaultComponents();
		CameraManager::Instance()->setCamera(CameraManager::PLAYER, hDebugCamera);
		//SceneNode *pCamSN = debugCamera->getCamSceneNode();

		}
	m_framesWithNoData = 0;
	m_framesWithData = 0;
#endif // #ifdef _XBOX
}
Esempio n. 15
0
Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Set<Ref<ImageTexture> >& image_map) {

	// children first..
	for(int i=0;i<p_node->get_child_count();i++) {


		Node *r = _fix_node(p_node->get_child(i),p_root,collision_map,p_flags,image_map);
		if (!r) {
			print_line("was erased..");
			i--; //was erased
		}
	}

	String name = p_node->get_name();

	bool isroot = p_node==p_root;


	if (!isroot && p_flags&SCENE_FLAG_REMOVE_NOIMP && _teststr(name,"noimp")) {

		memdelete(p_node);
		return NULL;
	}

	{

		List<PropertyInfo> pl;
		p_node->get_property_list(&pl);
		for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) {

			if (E->get().type==Variant::OBJECT || E->get().type==Variant::ARRAY || E->get().type==Variant::DICTIONARY) {
				_find_resources(p_node->get(E->get().name),image_map);
			}
		}

	}




	if (p_flags&SCENE_FLAG_CREATE_BILLBOARDS && p_node->cast_to<MeshInstance>()) {

		MeshInstance *mi = p_node->cast_to<MeshInstance>();

		bool bb=false;

		if ((_teststr(name,"bb"))) {
			bb=true;
		} else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"bb"))) {
			bb=true;

		}

		if (bb) {
			mi->set_flag(GeometryInstance::FLAG_BILLBOARD,true);
			if (mi->get_mesh().is_valid()) {

				Ref<Mesh> m = mi->get_mesh();
				for(int i=0;i<m->get_surface_count();i++) {

					Ref<FixedMaterial> fm = m->surface_get_material(i);
					if (fm.is_valid()) {
						fm->set_flag(Material::FLAG_UNSHADED,true);
						fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
						fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
						fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
					}
				}
			}
		}
	}

	if (p_flags&SCENE_FLAG_REMOVE_NOIMP && p_node->cast_to<AnimationPlayer>()) {
		//remove animations referencing non-importable nodes
		AnimationPlayer *ap = p_node->cast_to<AnimationPlayer>();

		List<StringName> anims;
		ap->get_animation_list(&anims);
		for(List<StringName>::Element *E=anims.front();E;E=E->next()) {

			Ref<Animation> anim=ap->get_animation(E->get());
			ERR_CONTINUE(anim.is_null());
			for(int i=0;i<anim->get_track_count();i++) {
				NodePath path = anim->track_get_path(i);

				for(int j=0;j<path.get_name_count();j++) {
					String node = path.get_name(j);
					if (_teststr(node,"noimp")) {
						anim->remove_track(i);
						i--;
						break;
					}
				}
			}

		}
	}


	if (p_flags&SCENE_FLAG_CREATE_IMPOSTORS && p_node->cast_to<MeshInstance>()) {

		MeshInstance *mi = p_node->cast_to<MeshInstance>();

		String str;

		if ((_teststr(name,"imp"))) {
			str=name;
		} else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"imp"))) {
			str=mi->get_mesh()->get_name();

		}


		if (p_node->get_parent() && p_node->get_parent()->cast_to<MeshInstance>()) {
			MeshInstance *mi = p_node->cast_to<MeshInstance>();
			MeshInstance *mip = p_node->get_parent()->cast_to<MeshInstance>();
			String d=str.substr(str.find("imp")+3,str.length());
			if (d!="") {
				if ((d[0]<'0' || d[0]>'9'))
					d=d.substr(1,d.length());
				if (d.length() && d[0]>='0' && d[0]<='9') {
					float dist = d.to_double();
					mi->set_flag(GeometryInstance::FLAG_BILLBOARD,true);
					mi->set_flag(GeometryInstance::FLAG_BILLBOARD_FIX_Y,true);
					mi->set_draw_range_begin(dist);
					mi->set_draw_range_end(100000);

					mip->set_draw_range_begin(0);
					mip->set_draw_range_end(dist);

					if (mi->get_mesh().is_valid()) {

						Ref<Mesh> m = mi->get_mesh();
						for(int i=0;i<m->get_surface_count();i++) {

							Ref<FixedMaterial> fm = m->surface_get_material(i);
							if (fm.is_valid()) {
								fm->set_flag(Material::FLAG_UNSHADED,true);
								fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
								fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
								fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
							}
						}
					}
				}
			}
		}
	}

    if (p_flags&SCENE_FLAG_CREATE_LODS && p_node->cast_to<MeshInstance>()) {

	MeshInstance *mi = p_node->cast_to<MeshInstance>();

	String str;

	if ((_teststr(name,"lod"))) {
	    str=name;
	} else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"lod"))) {
	    str=mi->get_mesh()->get_name();

	}


	if (p_node->get_parent() && p_node->get_parent()->cast_to<MeshInstance>()) {
	    MeshInstance *mi = p_node->cast_to<MeshInstance>();
	    MeshInstance *mip = p_node->get_parent()->cast_to<MeshInstance>();
	    String d=str.substr(str.find("lod")+3,str.length());
	    if (d!="") {
		if ((d[0]<'0' || d[0]>'9'))
		    d=d.substr(1,d.length());
		if (d.length() && d[0]>='0' && d[0]<='9') {
		    float dist = d.to_double();
		    mi->set_draw_range_begin(dist);
		    mi->set_draw_range_end(100000);

		    mip->set_draw_range_begin(0);
		    mip->set_draw_range_end(dist);

		    /*if (mi->get_mesh().is_valid()) {

			Ref<Mesh> m = mi->get_mesh();
			for(int i=0;i<m->get_surface_count();i++) {

			    Ref<FixedMaterial> fm = m->surface_get_material(i);
			    if (fm.is_valid()) {
				fm->set_flag(Material::FLAG_UNSHADED,true);
				fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
				fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
				fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
			    }
			}
		    }*/
		}
	    }
	}
    }
	if (p_flags&SCENE_FLAG_CREATE_COLLISIONS && _teststr(name,"colonly") && p_node->cast_to<MeshInstance>()) {

		if (isroot)
			return p_node;

		MeshInstance *mi = p_node->cast_to<MeshInstance>();
		Node * col = mi->create_trimesh_collision_node();

		ERR_FAIL_COND_V(!col,NULL);
		col->set_name(_fixstr(name,"colonly"));
		col->cast_to<Spatial>()->set_transform(mi->get_transform());
		p_node->replace_by(col);
		memdelete(p_node);
		p_node=col;

	} else if (p_flags&SCENE_FLAG_CREATE_COLLISIONS &&_teststr(name,"col") && p_node->cast_to<MeshInstance>()) {


		MeshInstance *mi = p_node->cast_to<MeshInstance>();

		mi->set_name(_fixstr(name,"col"));
		mi->create_trimesh_collision();
	} else if (p_flags&SCENE_FLAG_CREATE_ROOMS && _teststr(name,"room") && p_node->cast_to<MeshInstance>()) {


		if (isroot)
			return p_node;

		MeshInstance *mi = p_node->cast_to<MeshInstance>();
		DVector<Face3> faces = mi->get_faces(VisualInstance::FACES_SOLID);


		BSP_Tree bsptree(faces);

		Ref<RoomBounds> area = memnew( RoomBounds );
		area->set_bounds(faces);
		area->set_geometry_hint(faces);


		Room * room = memnew( Room );
		room->set_name(_fixstr(name,"room"));
		room->set_transform(mi->get_transform());
		room->set_room(area);

		p_node->replace_by(room);
		memdelete(p_node);
		p_node=room;

	} else if (p_flags&SCENE_FLAG_CREATE_ROOMS &&_teststr(name,"room")) {

		if (isroot)
			return p_node;

		Spatial *dummy = p_node->cast_to<Spatial>();
		ERR_FAIL_COND_V(!dummy,NULL);

		Room * room = memnew( Room );
		room->set_name(_fixstr(name,"room"));
		room->set_transform(dummy->get_transform());

		p_node->replace_by(room);
		memdelete(p_node);
		p_node=room;

		room->compute_room_from_subtree();

	} else if (p_flags&SCENE_FLAG_CREATE_PORTALS &&_teststr(name,"portal") && p_node->cast_to<MeshInstance>()) {

		if (isroot)
			return p_node;

		MeshInstance *mi = p_node->cast_to<MeshInstance>();
		DVector<Face3> faces = mi->get_faces(VisualInstance::FACES_SOLID);

		ERR_FAIL_COND_V(faces.size()==0,NULL);
		//step 1 compute the plane
		Set<Vector3> points;
		Plane plane;

		Vector3 center;

		for(int i=0;i<faces.size();i++) {

			Face3 f = faces.get(i);
			Plane p = f.get_plane();
			plane.normal+=p.normal;
			plane.d+=p.d;

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

				Vector3 v = f.vertex[i].snapped(0.01);
				if (!points.has(v)) {
					points.insert(v);
					center+=v;
				}
			}
		}

		plane.normal.normalize();
		plane.d/=faces.size();
		center/=points.size();

		//step 2, create points

		Transform t;
		t.basis.from_z(plane.normal);
		t.basis.transpose();
		t.origin=center;

		Vector<Point2> portal_points;

		for(Set<Vector3>::Element *E=points.front();E;E=E->next()) {

			Vector3 local = t.xform_inv(E->get());
			portal_points.push_back(Point2(local.x,local.y));
		}
		// step 3 bubbly sort points

		int swaps=0;

		do {
			swaps=0;

			for(int i=0;i<portal_points.size()-1;i++) {

				float a = portal_points[i].atan2();
				float b = portal_points[i+1].atan2();

				if (a>b) {
					SWAP( portal_points[i], portal_points[i+1] );
					swaps++;
				}

			}

		} while(swaps);


		Portal *portal = memnew( Portal );

		portal->set_shape(portal_points);
		portal->set_transform( mi->get_transform() * t);

		p_node->replace_by(portal);
		memdelete(p_node);
		p_node=portal;

	} else if (p_node->cast_to<MeshInstance>()) {

		//last attempt, maybe collision insde the mesh data

		MeshInstance *mi = p_node->cast_to<MeshInstance>();

		Ref<Mesh> mesh = mi->get_mesh();
		if (!mesh.is_null()) {

			if (p_flags&SCENE_FLAG_CREATE_COLLISIONS && _teststr(mesh->get_name(),"col")) {

				mesh->set_name( _fixstr(mesh->get_name(),"col") );
				Ref<Shape> shape;

				if (collision_map.has(mesh)) {
					shape = collision_map[mesh];

				} else {

					shape = mesh->create_trimesh_shape();
					if (!shape.is_null())
						collision_map[mesh]=shape;


				}

				if (!shape.is_null()) {
#if 0
					StaticBody* static_body = memnew( StaticBody );
					ERR_FAIL_COND_V(!static_body,NULL);
					static_body->set_name( String(mesh->get_name()) + "_col" );
					shape->set_name(static_body->get_name());
					static_body->add_shape(shape);

					mi->add_child(static_body);
					if (mi->get_owner())
						static_body->set_owner( mi->get_owner() );
#endif
				}

			}

			for(int i=0;i<mesh->get_surface_count();i++) {

				Ref<FixedMaterial> fm = mesh->surface_get_material(i);
				if (fm.is_valid()) {
					String name = fm->get_name();
					if (_teststr(name,"alpha")) {
						fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
						name=_fixstr(name,"alpha");
					}

					if (_teststr(name,"vcol")) {
						fm->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true);
						name=_fixstr(name,"vcol");
					}
					fm->set_name(name);
				}
			}

		}

	}




	return p_node;
}
Error EditorSceneImporterFBXConv::_parse_nodes(State& state,const Array &p_nodes,Node* p_base) {

	for(int i=0;i<p_nodes.size();i++) {

		Dictionary n = p_nodes[i];
		Spatial *node=NULL;
		bool skip=false;

		String id;
		if (n.has("id")) {
			id=_id(n["id"]);
		}

		print_line("ID: "+id);

		if (state.skeletons.has(id)) {

			Skeleton *skeleton = state.skeletons[id];
			node=skeleton;
			skeleton->localize_rests();
			print_line("IS SKELETON! ");
		} else if (state.bones.has(id)) {
			if (p_base)
				node=p_base->cast_to<Spatial>();
			if (!state.bones[id].has_anim_chan) {
				print_line("no has anim "+id);
			}
			skip=true;
		} else if (n.has("parts")) {
			//is a mesh
			MeshInstance *mesh = memnew( MeshInstance );
			node=mesh;

			Array parts=n["parts"];
			String long_identifier;
			for(int j=0;j<parts.size();j++) {

				Dictionary part=parts[j];
				if (part.has("meshpartid")) {
					String partid=part["meshpartid"];
					long_identifier+=partid;
				}
			}

			Ref<Mesh> m;

			if (state.mesh_cache.has(long_identifier)) {
				m=state.mesh_cache[long_identifier];
			} else {
				m = Ref<Mesh>( memnew( Mesh ) );

				//and parts are surfaces
				for(int j=0;j<parts.size();j++) {

					Dictionary part=parts[j];
					if (part.has("meshpartid")) {
						_add_surface(state,m,part);
					}
				}


				state.mesh_cache[long_identifier]=m;
			}

			mesh->set_mesh(m);
		}

		if (!skip) {

			if (!node) {
				node = memnew( Spatial );
			}

			node->set_name(id);
			node->set_transform(_get_transform(n));
			p_base->add_child(node);
			node->set_owner(state.scene);
		}


		if (n.has("children")) {
			Error err = _parse_nodes(state,n["children"],node);
			if (err)
				return err;
		}
	}

	return OK;
}
Esempio n. 17
0
Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {

	FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);

	if (r_err) {
		*r_err = ERR_CANT_OPEN;
	}

	ERR_FAIL_COND_V(!f, NULL);

	if (r_err) {
		*r_err = OK;
	}

	Spatial *scene = memnew(Spatial);

	Ref<ArrayMesh> mesh;
	mesh.instance();

	Map<String, Ref<Material> > name_map;

	bool generate_tangents = p_flags & IMPORT_GENERATE_TANGENT_ARRAYS;
	bool flip_faces = false;
	//bool flip_faces = p_options["force/flip_faces"];
	//bool force_smooth = p_options["force/smooth_shading"];
	//bool weld_vertices = p_options["force/weld_vertices"];
	//float weld_tolerance = p_options["force/weld_tolerance"];

	Vector<Vector3> vertices;
	Vector<Vector3> normals;
	Vector<Vector2> uvs;
	String name;

	Map<String, Map<String, Ref<SpatialMaterial> > > material_map;

	Ref<SurfaceTool> surf_tool = memnew(SurfaceTool);
	surf_tool->begin(Mesh::PRIMITIVE_TRIANGLES);

	String current_material_library;
	String current_material;
	String current_group;

	while (true) {

		String l = f->get_line().strip_edges();

		if (l.begins_with("v ")) {
			//vertex
			Vector<String> v = l.split(" ", false);
			ERR_FAIL_COND_V(v.size() < 4, NULL);
			Vector3 vtx;
			vtx.x = v[1].to_float();
			vtx.y = v[2].to_float();
			vtx.z = v[3].to_float();
			vertices.push_back(vtx);
		} else if (l.begins_with("vt ")) {
			//uv
			Vector<String> v = l.split(" ", false);
			ERR_FAIL_COND_V(v.size() < 3, NULL);
			Vector2 uv;
			uv.x = v[1].to_float();
			uv.y = 1.0 - v[2].to_float();
			uvs.push_back(uv);

		} else if (l.begins_with("vn ")) {
			//normal
			Vector<String> v = l.split(" ", false);
			ERR_FAIL_COND_V(v.size() < 4, NULL);
			Vector3 nrm;
			nrm.x = v[1].to_float();
			nrm.y = v[2].to_float();
			nrm.z = v[3].to_float();
			normals.push_back(nrm);
		} else if (l.begins_with("f ")) {
			//vertex

			Vector<String> v = l.split(" ", false);
			ERR_FAIL_COND_V(v.size() < 4, NULL);

			//not very fast, could be sped up

			Vector<String> face[3];
			face[0] = v[1].split("/");
			face[1] = v[2].split("/");
			ERR_FAIL_COND_V(face[0].size() == 0, NULL);
			ERR_FAIL_COND_V(face[0].size() != face[1].size(), NULL);
			for (int i = 2; i < v.size() - 1; i++) {

				face[2] = v[i + 1].split("/");
				ERR_FAIL_COND_V(face[0].size() != face[2].size(), NULL);
				for (int j = 0; j < 3; j++) {

					int idx = j;

					if (!flip_faces && idx < 2) {
						idx = 1 ^ idx;
					}

					if (face[idx].size() == 3) {
						int norm = face[idx][2].to_int() - 1;
						if (norm < 0)
							norm += normals.size() + 1;
						ERR_FAIL_INDEX_V(norm, normals.size(), NULL);
						surf_tool->add_normal(normals[norm]);
					}

					if (face[idx].size() >= 2 && face[idx][1] != String()) {
						int uv = face[idx][1].to_int() - 1;
						if (uv < 0)
							uv += uvs.size() + 1;
						ERR_FAIL_INDEX_V(uv, uvs.size(), NULL);
						surf_tool->add_uv(uvs[uv]);
					}

					int vtx = face[idx][0].to_int() - 1;
					if (vtx < 0)
						vtx += vertices.size() + 1;
					ERR_FAIL_INDEX_V(vtx, vertices.size(), NULL);

					Vector3 vertex = vertices[vtx];
					//if (weld_vertices)
					//	vertex.snap(Vector3(weld_tolerance, weld_tolerance, weld_tolerance));
					surf_tool->add_vertex(vertex);
				}

				face[1] = face[2];
			}
		} else if (l.begins_with("s ")) { //smoothing
			String what = l.substr(2, l.length()).strip_edges();
			if (what == "off")
				surf_tool->add_smooth_group(false);
			else
				surf_tool->add_smooth_group(true);
		} else if (/*l.begins_with("g ") ||*/ l.begins_with("usemtl ") || (l.begins_with("o ") || f->eof_reached())) { //commit group to mesh
			//groups are too annoying
			if (surf_tool->get_vertex_array().size()) {
				//another group going on, commit it
				if (normals.size() == 0) {
					surf_tool->generate_normals();
				}

				if (generate_tangents && uvs.size()) {
					surf_tool->generate_tangents();
				}

				surf_tool->index();

				print_line("current material library " + current_material_library + " has " + itos(material_map.has(current_material_library)));
				print_line("current material " + current_material + " has " + itos(material_map.has(current_material_library) && material_map[current_material_library].has(current_material)));

				if (material_map.has(current_material_library) && material_map[current_material_library].has(current_material)) {
					surf_tool->set_material(material_map[current_material_library][current_material]);
				}

				mesh = surf_tool->commit(mesh);

				if (current_material != String()) {
					mesh->surface_set_name(mesh->get_surface_count() - 1, current_material.get_basename());
				} else if (current_group != String()) {
					mesh->surface_set_name(mesh->get_surface_count() - 1, current_group);
				}

				print_line("Added surface :" + mesh->surface_get_name(mesh->get_surface_count() - 1));
				surf_tool->clear();
				surf_tool->begin(Mesh::PRIMITIVE_TRIANGLES);
			}

			if (l.begins_with("o ") || f->eof_reached()) {

				MeshInstance *mi = memnew(MeshInstance);
				mi->set_name(name);
				mi->set_mesh(mesh);

				scene->add_child(mi);
				mi->set_owner(scene);

				mesh.instance();
				current_group = "";
				current_material = "";
			}

			if (f->eof_reached()) {
				break;
			}

			if (l.begins_with("o ")) {
				name = l.substr(2, l.length()).strip_edges();
			}

			if (l.begins_with("usemtl ")) {

				current_material = l.replace("usemtl", "").strip_edges();
			}

			if (l.begins_with("g ")) {

				current_group = l.substr(2, l.length()).strip_edges();
			}

		} else if (l.begins_with("mtllib ")) { //parse material

			current_material_library = l.replace("mtllib", "").strip_edges();
			if (!material_map.has(current_material_library)) {
				Map<String, Ref<SpatialMaterial> > lib;
				Error err = _parse_material_library(current_material_library, lib, r_missing_deps);
				if (err == ERR_CANT_OPEN) {
					String dir = p_path.get_base_dir();
					err = _parse_material_library(dir.plus_file(current_material_library), lib, r_missing_deps);
				}
				if (err == OK) {
					material_map[current_material_library] = lib;
				}
			}
		}
	}

	/*
	TODO, check existing materials and merge?
	//re-apply materials if exist
	for(int i=0;i<mesh->get_surface_count();i++) {

		String n = mesh->surface_get_name(i);
		if (name_map.has(n))
			mesh->surface_set_material(i,name_map[n]);
	}
*/

	return scene;
}
void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, bool p_merge) {

	if (!p_merge)
		p_library->clear();


	 for(int i=0;i<p_scene->get_child_count();i++) {


		Node *child = p_scene->get_child(i);

		if (!child->cast_to<MeshInstance>()) {
			if (child->get_child_count()>0) {
				child=child->get_child(0);
				if (!child->cast_to<MeshInstance>()) {
					continue;
				}

			} else
				continue;


		}

		MeshInstance *mi = child->cast_to<MeshInstance>();
		Ref<Mesh> mesh=mi->get_mesh();
		if (mesh.is_null())
			 continue;

		int id = p_library->find_item_name(mi->get_name());
		if (id<0) {

			id=p_library->get_last_unused_item_id();
			p_library->create_item(id);
			p_library->set_item_name(id,mi->get_name());
		}


		p_library->set_item_mesh(id,mesh);

		Ref<Shape> collision;

		for(int j=0;j<mi->get_child_count();j++) {
#if 1
			Node *child2 = mi->get_child(j);
			if (!child2->cast_to<StaticBody>())
				continue;
			StaticBody *sb = child2->cast_to<StaticBody>();
			if (sb->get_shape_count()==0)
				continue;
			collision=sb->get_shape(0);
			if (!collision.is_null())
				break;
#endif
		}

		if (!collision.is_null()) {

			p_library->set_item_shape(id,collision);
		}

	 }


	 //generate previews!

	 if (1) {
		 Vector<int> ids = p_library->get_item_list();
		 RID vp = VS::get_singleton()->viewport_create();
		 VS::ViewportRect vr;
		 vr.x=0;
		 vr.y=0;
		 vr.width=EditorSettings::get_singleton()->get("grid_map/preview_size");
		 vr.height=EditorSettings::get_singleton()->get("grid_map/preview_size");
		 VS::get_singleton()->viewport_set_rect(vp,vr);
		 VS::get_singleton()->viewport_set_as_render_target(vp,true);
		 VS::get_singleton()->viewport_set_render_target_update_mode(vp,VS::RENDER_TARGET_UPDATE_ALWAYS);
		 RID scen = VS::get_singleton()->scenario_create();
		 VS::get_singleton()->viewport_set_scenario(vp,scen);
		 RID cam = VS::get_singleton()->camera_create();
		 VS::get_singleton()->camera_set_transform(cam, Transform() );
		 VS::get_singleton()->viewport_attach_camera(vp,cam);
		 RID light = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL);
		 RID lightinst = VS::get_singleton()->instance_create2(light,scen);
		 VS::get_singleton()->camera_set_orthogonal(cam,1.0,0.01,1000.0);


		 EditorProgress ep("mlib","Creating Mesh Library",ids.size());

		 for(int i=0;i<ids.size();i++) {

			int id=ids[i];
			Ref<Mesh> mesh = p_library->get_item_mesh(id);
			if (!mesh.is_valid())
				continue;
			AABB aabb= mesh->get_aabb();
			print_line("aabb: "+aabb);
			Vector3 ofs = aabb.pos + aabb.size*0.5;
			aabb.pos-=ofs;
			Transform xform;
			xform.basis=Matrix3().rotated(Vector3(0,1,0),Math_PI*0.25);
			xform.basis = Matrix3().rotated(Vector3(1,0,0),-Math_PI*0.25)*xform.basis;
			AABB rot_aabb = xform.xform(aabb);
			print_line("rot_aabb: "+rot_aabb);
			float m = MAX(rot_aabb.size.x,rot_aabb.size.y)*0.5;
			if (m==0)
				continue;
			m=1.0/m;
			m*=0.5;
			print_line("scale: "+rtos(m));
			xform.basis.scale(Vector3(m,m,m));
			xform.origin=-xform.basis.xform(ofs); //-ofs*m;
			xform.origin.z-=rot_aabb.size.z*2;
			RID inst = VS::get_singleton()->instance_create2(mesh->get_rid(),scen);
			VS::get_singleton()->instance_set_transform(inst,xform);
			ep.step("Thumbnail..",i);
			VS::get_singleton()->viewport_queue_screen_capture(vp);
			Main::iteration();
			Image img = VS::get_singleton()->viewport_get_screen_capture(vp);
			ERR_CONTINUE(img.empty());
			Ref<ImageTexture> it( memnew( ImageTexture ));
			it->create_from_image(img);
			p_library->set_item_preview(id,it);

//					print_line("loaded image, size: "+rtos(m)+" dist: "+rtos(dist)+" empty?"+itos(img.empty())+" w: "+itos(it->get_width())+" h: "+itos(it->get_height()));
			VS::get_singleton()->free(inst);
		 }

		 VS::get_singleton()->free(lightinst);
		 VS::get_singleton()->free(light);
		 VS::get_singleton()->free(vp);
		 VS::get_singleton()->free(cam);
		 VS::get_singleton()->free(scen);
	}


}
Esempio n. 19
0
void MeshInstanceEditor::_menu_option(int p_option) {

	Ref<Mesh> mesh = node->get_mesh();
	if (mesh.is_null()) {
		err_dialog->set_text(TTR("Mesh is empty!"));
		err_dialog->popup_centered_minsize();
		return;
	}

	switch (p_option) {
		case MENU_OPTION_CREATE_STATIC_TRIMESH_BODY:
		case MENU_OPTION_CREATE_STATIC_CONVEX_BODY: {

			bool trimesh_shape = (p_option == MENU_OPTION_CREATE_STATIC_TRIMESH_BODY);

			EditorSelection *editor_selection = EditorNode::get_singleton()->get_editor_selection();
			UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();

			List<Node *> selection = editor_selection->get_selected_node_list();

			if (selection.empty()) {
				Ref<Shape> shape = trimesh_shape ? mesh->create_trimesh_shape() : mesh->create_convex_shape();
				if (shape.is_null())
					return;

				CollisionShape *cshape = memnew(CollisionShape);
				cshape->set_shape(shape);
				StaticBody *body = memnew(StaticBody);
				body->add_child(cshape);

				Node *owner = node == get_tree()->get_edited_scene_root() ? node : node->get_owner();

				if (trimesh_shape)
					ur->create_action(TTR("Create Static Trimesh Body"));
				else
					ur->create_action(TTR("Create Static Convex Body"));

				ur->add_do_method(node, "add_child", body);
				ur->add_do_method(body, "set_owner", owner);
				ur->add_do_method(cshape, "set_owner", owner);
				ur->add_do_reference(body);
				ur->add_undo_method(node, "remove_child", body);
				ur->commit_action();
				return;
			}

			if (trimesh_shape)
				ur->create_action(TTR("Create Static Trimesh Body"));
			else
				ur->create_action(TTR("Create Static Convex Body"));

			for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {

				MeshInstance *instance = E->get()->cast_to<MeshInstance>();
				if (!instance)
					continue;

				Ref<Mesh> m = instance->get_mesh();
				if (m.is_null())
					continue;

				Ref<Shape> shape = trimesh_shape ? m->create_trimesh_shape() : m->create_convex_shape();
				if (shape.is_null())
					continue;

				CollisionShape *cshape = memnew(CollisionShape);
				cshape->set_shape(shape);
				StaticBody *body = memnew(StaticBody);
				body->add_child(cshape);

				Node *owner = instance == get_tree()->get_edited_scene_root() ? instance : instance->get_owner();

				ur->add_do_method(instance, "add_child", body);
				ur->add_do_method(body, "set_owner", owner);
				ur->add_do_method(cshape, "set_owner", owner);
				ur->add_do_reference(body);
				ur->add_undo_method(instance, "remove_child", body);
			}

			ur->commit_action();

		} break;

		case MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE:
		case MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE: {

			if (node == get_tree()->get_edited_scene_root()) {
				err_dialog->set_text(TTR("This doesn't work on scene root!"));
				err_dialog->popup_centered_minsize();
				return;
			}

			bool trimesh_shape = (p_option == MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE);

			Ref<Shape> shape = trimesh_shape ? mesh->create_trimesh_shape() : mesh->create_convex_shape();
			if (shape.is_null())
				return;

			CollisionShape *cshape = memnew(CollisionShape);
			cshape->set_shape(shape);

			Node *owner = node->get_owner();

			UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();

			if (trimesh_shape)
				ur->create_action(TTR("Create Trimesh Shape"));
			else
				ur->create_action(TTR("Create Convex Shape"));

			ur->add_do_method(node->get_parent(), "add_child", cshape);
			ur->add_do_method(node->get_parent(), "move_child", cshape, node->get_index() + 1);
			ur->add_do_method(cshape, "set_owner", owner);
			ur->add_do_reference(cshape);
			ur->add_undo_method(node->get_parent(), "remove_child", cshape);
			ur->commit_action();

		} break;

		case MENU_OPTION_CREATE_NAVMESH: {

			Ref<NavigationMesh> nmesh = memnew(NavigationMesh);

			if (nmesh.is_null())
				return;

			nmesh->create_from_mesh(mesh);
			NavigationMeshInstance *nmi = memnew(NavigationMeshInstance);
			nmi->set_navigation_mesh(nmesh);

			Node *owner = node == get_tree()->get_edited_scene_root() ? node : node->get_owner();

			UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
			ur->create_action(TTR("Create Navigation Mesh"));

			ur->add_do_method(node, "add_child", nmi);
			ur->add_do_method(nmi, "set_owner", owner);

			ur->add_do_reference(nmi);
			ur->add_undo_method(node, "remove_child", nmi);
			ur->commit_action();
		} break;

		case MENU_OPTION_CREATE_OUTLINE_MESH: {

			outline_dialog->popup_centered(Vector2(200, 90));
		} break;
	}
}
Esempio n. 20
0
void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, List<PlotMesh> &plot_meshes, List<PlotLight> &plot_lights) {

	MeshInstance *mi = Object::cast_to<MeshInstance>(p_at_node);
	if (mi && mi->get_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT) && mi->is_visible_in_tree()) {
		Ref<Mesh> mesh = mi->get_mesh();
		if (mesh.is_valid()) {

			bool all_have_uv2 = true;
			for (int i = 0; i < mesh->get_surface_count(); i++) {
				if (!(mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_TEX_UV2)) {
					all_have_uv2 = false;
					break;
				}
			}

			if (all_have_uv2 && mesh->get_lightmap_size_hint() != Size2()) {
				//READY TO BAKE! size hint could be computed if not found, actually..

				AABB aabb = mesh->get_aabb();

				Transform xf = get_global_transform().affine_inverse() * mi->get_global_transform();

				if (AABB(-extents, extents * 2).intersects(xf.xform(aabb))) {
					PlotMesh pm;
					pm.local_xform = xf;
					pm.mesh = mesh;
					pm.path = get_path_to(mi);
					pm.instance_idx = -1;
					for (int i = 0; i < mesh->get_surface_count(); i++) {
						pm.instance_materials.push_back(mi->get_surface_material(i));
					}
					pm.override_material = mi->get_material_override();
					plot_meshes.push_back(pm);
				}
			}
		}
	}

	Spatial *s = Object::cast_to<Spatial>(p_at_node);

	if (!mi && s) {
		Array meshes = p_at_node->call("get_bake_meshes");
		if (meshes.size() && (meshes.size() & 1) == 0) {
			Transform xf = get_global_transform().affine_inverse() * s->get_global_transform();
			for (int i = 0; i < meshes.size(); i += 2) {
				PlotMesh pm;
				Transform mesh_xf = meshes[i + 1];
				pm.local_xform = xf * mesh_xf;
				pm.mesh = meshes[i];
				pm.instance_idx = i / 2;
				if (!pm.mesh.is_valid())
					continue;
				pm.path = get_path_to(s);
				plot_meshes.push_back(pm);
			}
		}
	}

	Light *light = Object::cast_to<Light>(p_at_node);

	if (light && light->get_bake_mode() != Light::BAKE_DISABLED) {
		PlotLight pl;
		Transform xf = get_global_transform().affine_inverse() * light->get_global_transform();

		pl.local_xform = xf;
		pl.light = light;
		plot_lights.push_back(pl);
	}
	for (int i = 0; i < p_at_node->get_child_count(); i++) {

		Node *child = p_at_node->get_child(i);
		if (!child->get_owner())
			continue; //maybe a helper

		_find_meshes_and_lights(child, plot_meshes, plot_lights);
	}
}