Add decal to object on intersection

Hi, I’m having trouble trying to add a decal to an intersected object. Everything seems fine when I add it to the scene but I can’t figure out how to transform the position from world space to object’s local space :frowning:

Sandbox and code:

  const hit = raycaster.intersectObjects(scene.children)[0];
  const position = hit.point;
  const normal = hit.face.normal;
  const object = hit.object;

  const inverseMatrix = new THREE.Matrix4().copy(object.matrixWorld).invert();
  const localNormal = normal.clone().transformDirection(inverseMatrix);
  const up = new THREE.Vector3(0, 0, 1);
  const quaternion = new THREE.Quaternion().setFromUnitVectors(
    up,
    localNormal
  );

  const localPosition = position.clone().applyMatrix4(inverseMatrix);

  let geometry = new DecalGeometry(
    object,
    localPosition,
    new THREE.Euler().setFromQuaternion(quaternion),
    new THREE.Vector3(1, 1, 1)
  );

  const mesh = new THREE.Mesh(geometry, material);
  object.add(mesh);

Just the position or also the orientation? To transform position from world to local, just add the object to the parent object, the call parentObject.worldToLocal(object.position)

2 Likes

Both position and the orientation. I got the orientation right but was struggling with the position.

ParentObject.worldTolocal(object.position) is one of the things I tried, but for some reason I kept trying to use that vector in the DecalGeometry constructor. It didn’t cross my mind to apply it to the mesh instead. Must’ve been too tired… Tried again after your reply and it’s working. Thanks a lot :pray:

I updated the sandbox if anyone needs it.