'Applying user selected texture to cube dynamically?
I’m creating a cube using BoxGeometry and trying to apply the texture that the user has selected.
I created a raycaster and use that raycaster inside mouse down event. If the object is present on cursor position then a user-selected texture gets applied.
So far everything works fine. Then I added if-else condition if the user selected single image for texture then that single image gets applied whole body of cube means all side of cube gets that image as material.
But if the user selected more than one image suppose three images then only three sides of cube get material. This also works very well.
Now a real problem when user select only three images remaining side of cube remain black and that is okay only material applied side shows up.
Now if user again select a single image and click on cube to apply single image texture to whole body again ray caster gives problem that “–can’t access property “side”, the material is undefined–” so this callback function which i added to select image files
function onUserMultiImageSelect(event) {
materialArray.length = 0;
length = multiFilesId.files.length;
let multiImage = [];
let userMultiImageUrl = [];
for (let i = 0; i < length; i++) {
multiImage[i] = multiFilesId.files.item(i);
userMultiImageUrl[i] = URL.createObjectURL(multiImage[i]);
materialArray.push(new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load(userMultiImageUrl[i]),side:THREE.DoubleSide }));
}
isTextureSelect = true;
}
this is callback funtion which gets called when i click on object to apply texture
function onMouseButtonDown(event) {
var rect = event.target.getBoundingClientRect();
var mouseX = event.clientX - rect.left;
var mouseY = event.clientY - rect.top;
let raycaster = new THREE.Raycaster();
let pointer = new THREE.Vector2();
pointer.set((mouseX / window.innerWidth) * 2 - 1, -(mouseY / window.innerHeight) * 2 + 1);
raycaster.setFromCamera(pointer, camera);
const intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
var curentIntersectedObject = intersects[0];
if (isTextureSelect) {
if(length == 1){
var singleImage = multiFilesId.files.item(0);
var singleImageUrl = URL.createObjectURL(singleImage);
var texture = new THREE.TextureLoader().load(singleImageUrl);
curentIntersectedObject.object.material = new THREE.MeshBasicMaterial({ map: texture });
}else{
curentIntersectedObject.object.material = materialArray;
}
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|