Jump to content

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


joeBImagine
 Share

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?

 

Link to comment
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.

Link to comment
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.  

Link to comment
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?

Link to comment
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?

Link to comment
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.

 

Link to comment
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)

 

Link to comment
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!!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...