Hi Experts,
I’ve created 5000 box model (Gltf Model) by using InstancedMesh and when I clicked the any instance I’m changing the color of instance. But while clicked box’s color being changed the other instances returned into black color. Although every box’s have a material like a cardboard it’s being dissappear. How can I fix this issue ?
Additionally I would like to remove clicked instance’s material and when I clicked another instance I would like to set previous instance’s material again. Shortly, I would like to set original material to the previous instance. If anyone help me about this topic, I would very appreciated.
Here is my code blocks;
Adding cube to the scene:
addCubeToScene() {
this.oDracoLoader = new DRACOLoader();
this.oDracoLoader.setDecoderPath("./draco/");
this.oGltfLoader = new GLTFLoader();
this.oGltfLoader.setDRACOLoader(this.oDracoLoader);
this.oDracoLoader.preload();
this.oGltfLoader.load(BoxModel, function(oObject) {
let oObjectGeometry = oObject.scene.children[0].geometry;
let oTexture = new THREE.TextureLoader().load(BoxTexture);
let oMaterial = new THREE.MeshLambertMaterial({
map: oTexture,
side: THREE.DoubleSide
});
oMesh = new THREE.InstancedMesh(oObjectGeometry, oMaterial, 5000);
oMesh.userData.PackageInformations = [];
let translateMatrix = new THREE.Matrix4();
let scaleMatrix = new THREE.Matrix4().makeScale(1, 1, 1);
let finalMatrix = new THREE.Matrix4();
for (let index = 0; index < 5000; ++index) {
translateMatrix.makeTranslation(
Math.random() * 5000,
Math.random() * 5000,
Math.random() * 2500
);
finalMatrix.multiplyMatrices(translateMatrix, scaleMatrix);
oMesh.userData.PackageInformations.push({
PackageZone: "A1Y",
PackageInstanceID: index,
PackageName: "Box-" + index,
PackageOriginalMaterial: oMesh.material
});
oMesh.setMatrixAt(index, finalMatrix);
}
oMesh.instanceMatrix.needsUpdate = true;
oThis.scene.add(oMesh);
oThis.renderScene();
});
},
Here is the clicking process:
onMouseClick(oEvent) {
oEvent.preventDefault();
oEvent.stopPropagation();
oMouse.x =
(oEvent.offsetX / this.renderer.domElement.clientWidth) * 2 - 1;
oMouse.y =
-(oEvent.offsetY / this.renderer.domElement.clientHeight) * 2 + 1;
oRaycaster.setFromCamera(oMouse, this.camera);
var oIntersects = oRaycaster.intersectObjects(this.scene.children, true);
if (oIntersects[0] && oIntersects[0].object) {
var oObject = oIntersects[0].object;
if (oObject instanceof THREE.InstancedMesh) {
var oBoxName = `Box-${oIntersects[0].instanceId}`;
var oClickedBoxData = oMesh.userData.PackageInformations.filter(
function(oItem) {
if (oIntersects[0].instanceId == oItem.PackageInstanceID) {
var oClickedBoxInstance = oMesh.getMatrixAt(oIntersects[0].instanceId, new THREE.Matrix4()); // it returns undefined. Do I something wrong ?
oMesh.setColorAt(oIntersects[0].instanceId, new THREE.Color().set(0xffffff * Math.random())); // it changes to the instance color randomly, but the other instances returned into black color
oMesh.instanceMatrix.needsUpdate = true;
oMesh.instanceColor.needsUpdate = true;
return oItem;
}
}
);
}
oThis.renderScene();
}
}
Here is the original image;
Here is the screenshot after clicked any instanced mesh;