Back to the Shapespark home page

Video as texture - again

Continuing the discussion from Youtube Video as Texture:

Hi All,
I’m trying to follow instructions from the topic above and I’m struggling a bit (new to Shapespark and Javascript).
So the goal is to have one object with multiple video texures activated by a click on other objects. The code from Wojtek works very well on different target objects but if I apply textures to just one of them it works only once for some reason.

So in the example below if I click on ObjectRug - RugMaterial is updated. If I then click on ObjectCurtain A - RugMaterial is updated again to a new video texture. I guess this kind of works by pure luck… But, if I click on ObjectRug back again, the video texture does not update… Anyone knows why it doesn’t work?
Thanks in advance!
Cheers
Wojtek

setUpExternalVideoTexture('ObjectRug', 'RugMaterial', 'https://cdn0.shapespark.com/demo/ASSETS/textures/dots-video.mp4', false, true);

setUpExternalVideoTexture('ObjectCurtain A', 'RugMaterial', 'https://cdn0.shapespark.com/demo/ASSETS/textures/lines-video.mp4', false, true);

Right, with this approach you will have two click handlers on the same object, so one of them will receive and capture the click, and the other one will not be invoked. You would need to change Wojtek’s code to only register one onNodeTypeClicked handler and switch between the textures within this handler.

Thank you, not sure if I follow (well, clearly I don’t:-) - ObjectRug and Object curtain are not the same object? So I’m trying to click on on the rug and on the curtain to swap the video texture on a material applied to a completely different (third) object…

Please see below the full script I’m using, sorry to be a pain…
Cheers
Wojtek

<script>
  const viewer = WALK.getViewer();

  viewer.setMaterialEditable('RugMaterial');
  
  function createVideoTexture(src, muted, loop) {
    const video = document.createElement('video');
    video.src = src;
    video.autoplay = false;
    video.muted = muted;
    video.loop = loop;
    return viewer.createTextureFromHtmlVideo(video);
  }
  
  function setUpExternalVideoTexture(triggerNodeTypeName, materialName,
                                     videoSrc, muted, loop) {
    let videoTexture = null;
    viewer.onNodeTypeClicked(triggerNodeTypeName, function() {
      // Create the video texture only once.
      if (!videoTexture) {
        videoTexture = createVideoTexture(videoSrc, muted, loop);
        const material = viewer.findMaterial(materialName);
        material.baseColorTexture = videoTexture;
      }
      if (!videoTexture.isPlaying) {
        videoTexture.play();
      } else {
        videoTexture.pause();
      }
      viewer.requestFrame();
      return true;
    });
  }

  setUpExternalVideoTexture('ObjectRug', 'RugMaterial', 'https://cdn0.shapespark.com/demo/ASSETS/textures/dots-video.mp4', false, true);

  setUpExternalVideoTexture('ObjectCurtain A', 'RugMaterial', 'https://cdn0.shapespark.com/demo/ASSETS/textures/lines-video.mp4', false, true);

</script>

I’m sorry about the confusion, I have misread your first post. Wojtek’s code assumed that a texture needs to be replaced only once and then it stays assigned to the material. In your case you need to move the replacing logic out of the if, so the texture is replaced on each click. Like this:

      ...
      if (!videoTexture) {
        videoTexture = createVideoTexture(videoSrc, muted, loop);
      }
      const material = viewer.findMaterial(materialName);
      material.baseColorTexture = videoTexture;
      if (!videoTexture.isPlaying) {
      ...
1 Like

OMG. It’s working!
Thank you so much!
Cheers
Wojtek