joeBImagine

Dynamically Change textures of selected mesh on HTML click of DOM element

Recommended Posts

Hello Babylon community!!

I am having an issue that I am not sure how to resolve.  Here is my github.io to get a better sense of the problem:

https://jbimagine.github.io/#

In the link above I have a babylon file loaded, and in the side ui (if you click on the gear icon) several texture HTML DOM elements.  What I am trying to do is when you click on the mesh, then click on the texture swatch in the ui, the texture on the mesh will change.  

For some reason however, it is not working correctly.  I click on the mesh, then click on the swatch, then have to click back on the mesh for the texture to actually change.  Note that I am not using the set name of the mesh, but rather a const created from the pick.result so that it will be based off of any loaded mesh.  

Any help on what I am missing (probably something stupid easy) would be awesome! 

Also I am curious if it would have been easier, and more efficient to use the gui?

 

Share this post


Link to post
Share on other sites

Working for me on an Android tabled. Touch away from object which is deselected. Select texture touch object texture changed on object, touch new texture this texture applied to object.

 

Share this post


Link to post
Share on other sites

I would say it can be fixed in two ways:
1. window.addEventListener("click",...) should just be for the canvas, as clicks on the DOM are already captured.
2. pickResult - check for pickResult.hit before assigning to selected mesh, otherwise it is null (then you can't assign the material).

Also, I think you found a good use case where DOM makes more sense than GUI.  It's simple and easy to use.  You could accomplish with a full screen GUI using Images with textures, but I don't see how you are going to easily get the "overflow auto" working with GUI.

Share this post


Link to post
Share on other sites

Thank you for the suggestions @brianzinn.  If I am understanding correctly you are saying this correct:  

             window.addEventListener(canvas, () => {
				const pickResult = scene.pick(scene.pointerX, scene.pointerY);
				console.log(pickResult.hit);
				let selectedMesh = null;
				if (pickResult.hit === true) {
					selectedMesh = pickResult.pickedMesh;
					if (selectedMesh && currentFabric) {
						selectedMesh.material = currentFabric;
					}
				}
				console.log(selectedMesh);
				console.log(currentFabric, 'currentMesh');
			});

If I am inputting that correctly, the texture change no longer works.  

Share this post


Link to post
Share on other sites
13 minutes ago, joeBImagine said:

Thank you for the suggestions @brianzinn.  If I am understanding correctly you are saying this correct:  


             window.addEventListener(canvas, () => {
				const pickResult = scene.pick(scene.pointerX, scene.pointerY);
				console.log(pickResult.hit);
				let selectedMesh = null;
				if (pickResult.hit === true) {
					selectedMesh = pickResult.pickedMesh;
					if (selectedMesh && currentFabric) {
						selectedMesh.material = currentFabric;
					}
				}
				console.log(selectedMesh);
				console.log(currentFabric, 'currentMesh');
			});

If I am inputting that correctly, the texture change no longer works.  

Hi joe...

selectedMesh set as global var. After click on material, apply to global var (selectedMesh).

Does that make sense?

Share this post


Link to post
Share on other sites
4 hours ago, joeBImagine said:

you are saying this correct

yes, I think just remove the line "let selectedMesh = null", because then you are creating a new variable that is not in scope with the other calls, which require a shared (or global variable).

Also, on your github.io page you have "const selectedMesh", that means you don't intend to re-assign it, so just maybe just declare "var selectedMesh;" at the top of your main.js file?

Share this post


Link to post
Share on other sites

@Arte @brianzinn  Forgive the delay in a response!!  So I've set the selectedMesh as a global variable above my main function.  But still not able to change textures.  I think it may be something to do with the window.addEventListener(canvas,..) as now I am not able to generate console.log reports when I select the mesh but I am not certain with my limited knowledge.  Updated github.

 

Share this post


Link to post
Share on other sites

I don't know what happened with formatting here, but would likely go this way, so you don't need to call scene.pick yourself:

scene.onPointerObservable.add((evt) => {
  if (evt.pickInfo.hit && evt.pickInfo.pickedMesh) {
    let mesh = evt.pickInfo.pickedMesh
  }
}, PointerEventTypes.POINTERDOWN)

 

Share this post


Link to post
Share on other sites

@brianzinn  thank you for that, looks like I was doing it wrong.  But I did with your last tidbit and some tweaking, get it to work properly:  

//CREATE THE HIGHLIGHT LAYER
			let h1 = new BABYLON.HighlightLayer('hl', scene);
			//SET THE INITIAL STATE OF THE lastClickedMesh var
			let lastClickedMesh = null;
			let mesh = null;

			//ADD A POINTERDOWN OBSERVABLE 
			scene.onPointerObservable.add(evt => {
				
				if (evt.pickInfo.hit && evt.pickInfo.pickedMesh !== undefined) {
					//STORES THE MESH INTO A VARIABLE
					 mesh = evt.pickInfo.pickedMesh;
					let fabrics = document.querySelectorAll('.fabrics');
					let currentFabric;
					fabrics.forEach(function(fabric) {
						fabric.addEventListener('click', evt => {
							console.log(obj[evt.target.id]);
							currentFabric = obj[evt.target.id];
							if(mesh && currentFabric){
								mesh.material = currentFabric;
								//console.log(evt.pickInfo.pickedMeshmesh);
							}else {
								mesh.removeMesh(mesh);
							}
						});
					});
					//HIGHLIGHTS THE CURRENT SELECTION
					if (newMeshes) {
						if (lastClickedMesh !== null) {
							
							h1.removeMesh(lastClickedMesh);
						}
						lastClickedMesh = mesh;
						h1.addMesh(lastClickedMesh, BABYLON.Color3.FromHexString('#4c90ef'));
					}
				} else {
					h1.removeMesh(lastClickedMesh);
				}

				
			}, BABYLON.PointerEventTypes.POINTERDOWN);
		}
	);

I can't emphasize enough how awesome this community is :D!!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.