McNidday Posted October 2, 2019 Share Posted October 2, 2019 Hey guys, here's another random babylonjs newbie hoping to get some help :-) So i have been playing around with babylonjs for a while and i get better at it everyday but i just hit this stumbling block that i can't seem to figure out I have created a sample box for a demonstration of this frustration, get it ? // Create sample box const sampleBox = BABYLON.MeshBuilder.CreateBox('sampleBox', { size: 10, updatable: true }, scene, true); sampleBox.isPickable = true; sampleBox.position = new Vector3(0, 0, 0); let verticesCount = sampleBox.getTotalVertices(); Then i used multimaterial to assign image textures to four of the faces of the sample box // Create four standard materials let material0 = new StandardMaterial('material0', scene); material0.diffuseTexture = new Texture('/some0_image.jpg', scene); material0.diffuseTexture.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE; material0.diffuseTexture.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE; material0.specularColor = new Color3.Black(); let material1 = new StandardMaterial('material2', scene); material1.diffuseTexture = new Texture('/some1_image.jpg', scene); material1.diffuseTexture.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE; material1.diffuseTexture.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE; material1.specularColor = new Color3.Black(); let material2 = new StandardMaterial('material2', scene); material2.diffuseTexture = new Texture('/some2_image.jpg', scene); material2.diffuseTexture.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE; material2.diffuseTexture.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE; material2.specularColor = new Color3.Black(); let material3 = new StandardMaterial('material3', scene); material3.diffuseTexture = new Texture('/some3_image.jpg', scene); material3.diffuseTexture.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE; material3.diffuseTexture.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE; material3.specularColor = new Color3.Black(); // Define the multimaterial let maltimat = new MultiMaterial('multi', scene); maltimat.subMaterials.push(material0); maltimat.subMaterials.push(material1); maltimat.subMaterials.push(material2); maltimat.subMaterials.push(material3); // Assign mesh material to the mesh sampleBox.material = maltimat; // Define the subMeshes for the sample box new BABYLON.SubMesh(2, 0, verticesCount, 0, 6, sampleBox); new BABYLON.SubMesh(1, 0, verticesCount, 6, 6, sampleBox); new BABYLON.SubMesh(3, 0, verticesCount, 12, 6, sampleBox); new BABYLON.SubMesh(0, 0, verticesCount, 16, 6, sampleBox); So this is where the problem that has been bumming me for days comes in. I would like to change the texture of one of the faces when it is clicked, so one of the solutions i came up with to this problem was to change the submeshes material index to one of the four materials like below and it works partially. So in solution one, when a pick event happens i would access pickedMesh.subMeshes[some_index] and it would change the submeshes texture material to another one, the problem i encountered with this was Getting the correct index from the pickInfo to select the submesh from the submeshes array and change it, tried using faceId, bad idea and submeshId keeps returning the value 0 when i select any of all the faces The other problem with this approach was, i wanted to assign material to a face that has not been covered by the BABYLON.Submesh by getting the startIndex and indexCount automatically with the pickInfo and pushing the new data to the sampleBoxe's submesh array, In this case if the submeshId is not available, Yes i declared 4 subMeshes for a reason. scene.onPointerPick = (event, pickInfo) => { if (pickInfo.hit) { let indices = pickInfo.pickedMesh.getIndices(); let faceId = pickInfo.faceId; let index0 = indices[pickInfo.faceId * 3]; let index1 = indices[pickInfo.faceId * 3 + 1]; let index2 = indices[pickInfo.faceId * 3 + 2]; let submeshId = pickInfo.submeshId; let positions = pickInfo.pickedMesh.getVerticesData(VertexBuffer.PositionKind); sampleBox.submeshes[faceId].materialIndex = 0; // or using submeshId, which just returns 0 for some reson uuuuurrrrgh if (!submeshId) { // How do i get the indexStart and the indexCount from the pick info new BABYLON.subMesh(0,0,verticesCount, indexStart, indexCount, sampleBox) } else { sampleBox.submeshes[submeshId].materialIndex = 0; } // or hard coding it but whats the essence it would just change a face material that's // not even facing the screen and that's not my intent sampleBox.submeshes[2].materialIndex = 0; } } The other way to go about this was to use vertexData but i couldn't get this to work with images only manipulating the colors of the facets on pick event and used updateVertexData to update the colorKind and it worked like a charm. If there is a way to use vertexData to change a face material, i would appreciate and even buy you a soda and give you a hug if you were near me ? let positions = [-5, 2, -3, -7, -2, -3, -3, -2, -3, 5, 2, 3, 7, -2, 3, 3, -2, 3]; let indices = [0, 1, 2, 3, 4, 5]; let colors = [1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1]; let vertexData = new BABYLON.VertexData(); vertexData.positions = positions; vertexData.indices = indices; vertexData.colors = colors; vertexData.applyToMesh(sampleBox); Quote I am not in a position to send a live file or a playground link, so am sorry for that but hope you can recreate the scene with the code snippets above or visualise Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.