IMG_5303.MP4.mp4

IMG_5301.MP4.mp4

  1. Before getting started register a new account at DeepAI: https://deepai.org/
  2. Get API key at your account
  3. Put API key as an argument to deepai.setApiKey() function
  4. Upload your own model or get one from the Sketcfab
  5. Replace the name of the object you want to change the AI texture to at ‘targetObjectName’ constant
  6. Copy the code and paste it as a custom code into your AR application 💫
this.activeSceneModel.$parent.emitter.addListener("geenee-model-placed", () => {
  const targetObjectName = "Lambo_Lambo_Mat_0"; // The name of the object we want to change the material to
  const material = this.object3D.getObjectByName(targetObjectName).material;
  console.log(this.object3D);
  console.log(material);

  // AI Logic
  const submitBtn = document.getElementsByClassName("ai-input-submit")[0];
  const aiPromptInput = document.getElementsByClassName("ai-input-input")[0];
  const netImgBtn = document.getElementsByClassName("ai-next-img")[0];
  let AItexture = new THREE.Texture();
  let AItextureNum = 0;
  let AItextures = [];

  // Set API Key
  deepai.setApiKey("Your API Key");

  // Change texture
  netImgBtn.addEventListener("click", async (e) => {
    changeAITextureOption();
  });

  submitBtn.addEventListener("click", async (e) => {
    const prompt = aiPromptInput.value;
    console.log(prompt);

    e.preventDefault();

    // Show loader
    document.getElementById("dots-transparent").style.display = "flex";

    // Run AI Image Generator
    (async function () {
      var resp = await deepai.callStandardApi("stable-diffusion", {
        text: prompt,
      });
      console.log(resp.output_url);
      setAITexture(resp.output_url);
    })();
  });

  const changeAITextureOption = () => {
    switch (AItextureNum) {
      case 0:
        AItextureNum = 1;
        AItexture = AItextures[AItextureNum];
        material.map = AItexture;
        break;
      case 1:
        AItextureNum = 2;
        AItexture = AItextures[AItextureNum];
        material.map = AItexture;
        break;
      case 2:
        AItextureNum = 3;
        AItexture = AItextures[AItextureNum];
        material.map = AItexture;
        break;
      case 3:
        AItextureNum = 0;
        AItexture = AItextures[AItextureNum];
        material.map = AItexture;
        break;
    }
  };

  const setAITexture = (url) => {
    AItextures = [];
    //Slice AI texture to 4 pieces, because deepai returns 4 generated images at once
    getSlicedTextures(url).then((textureUrls) => {
      textureUrls.forEach((textureUrl) => {
        const texture = new THREE.TextureLoader().load(textureUrl);
        texture.wrapS = THREE.RepeatWrapping;
        texture.wrapT = THREE.RepeatWrapping;
        //texture.repeat.set(0.5, 0.5);
        AItextures.push(texture);
      });

      AItextureNum = 0;
      AItexture = AItextures[AItextureNum];
      material.map = AItexture;
      document.getElementById("dots-transparent").style.display = "none";
      //console.dir(textureUrls);
    });
  };
});

const getSlicedTextures = (url) => {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.src = url;
    img.crossOrigin = "anonymous";
    img.onload = () => {
      let canvas = document.createElement("canvas");
      let ctx = canvas.getContext("2d");
      let w2 = img.width / 2,
        h2 = img.height / 2;

      let parts = [];

      for (let i = 0; i < 4; i++) {
        let x = (-w2 * i) % (w2 * 2),
          y = h2 * i <= h2 ? 0 : -h2;
        canvas.width = w2;
        canvas.height = h2;

        ctx.drawImage(img, x, y, w2 * 2, h2 * 2);

        parts.push(canvas.toDataURL());
      }
      resolve(parts);
    };
    img.onerror = reject;
  });
};

// this function will work cross-browser for loading scripts asynchronously
const loadScript = (_name, src, callback) => {
  let s;
  let r;
  let t;
  r = false;
  s = document.createElement("script");
  s.type = "text/javascript";
  s.src = src;
  s.onload = s.onreadystatechange = () => {
    if (!r && (!this.readyState || this.readyState == "complete")) {
      r = true;
      callback(_name);
    }
  };
  t = document.getElementsByTagName("script")[0];
  t.parentNode.insertBefore(s, t);
};

// After all necessary scripts loaded
const onLoadScript = (_name) => {
  if (_name == "deepai") {
    // do something after script loaded.
    console.log("deepai is loaded");
  }
};

//Load deepai script
loadScript("deepai", "<https://cdnjs.deepai.org/deepai.min.js>", onLoadScript);

//Render css & html
const renderHtml = () => {
  const wrapper = document.createElement("div");
  wrapper.innerHTML = html;
  document.body.appendChild(wrapper);
};

const renderCss = () => {
  const style = document.createElement("style");
  style.textContent = css;
  document.head.append(style);
};

const html = `
<div class="ai-input-wrapper">
    <input class="ai-input-input" type="text" placeholder="Enter your prompt" />
    <div class="ai-input-submit">
        Run
    </div>
    <div class="ai-next-img">
        Next
    </div>
</div>
<div id="dots-transparent" class="dots dots-transparent full-screen">
    <div class="pulse1"></div>
    <div class="pulse2"></div>
    <div class="pulse3"></div>
</div>`;

const css = `
.ai-input-wrapper {
  display: flex;
  position: absolute;
  bottom: 100px;
  left: 50%;
  transform: translate(-50%, 0);
  width: 320px;
  height: 50px;
  flex-direction: row;
  justify-content: space-around;
}

.ai-input-input {
  display: flex;
  width: 200px;
  padding: 8px;
  height: 50px;
  font-size: 16px;
  border: 1px solid #000;
  background: rgba(255,255,255,0.75);
  border-radius: 10px;
}

.ai-input-input:focus {
  outline: 1px solid #000;
}

.ai-input-submit {
  display: block;
  height: 50px;
  width: 50px;
  padding: 13px 0;
  background: #fff;
  color: #000;
  border: 1px solid #000;
  border-radius: 10px;
  background: rgba(255,255,255,0.75);
  cursor: pointer;
  text-align: center;
}
.ai-next-img {
  display: block;
  height: 50px;
  width: 50px;
  padding: 13px 0;
  background: #fff;
  color: #000;
  background: rgba(255,255,255,0.75);
  border: 1px solid #000;
  border-radius: 10px;
  cursor: pointer;
  text-align: center;
}
.dots-transparent {
  background-color: rgba(0, 0, 0, 0.25);
  background-image: none;
  display: none;
}
.dots {
  display: none;
  justify-content: center;
  align-items: center;
  z-index: 20;
  top: 0;
}
.full-screen {
  position: absolute;
  width: 100%;
  height: 100%;
}
.dots > div {
  display: inline-block;
  width: 20px;
  height: 20px;
  margin: 2px;
  border-radius: 100%;
  background-color: #FFFFFF;
  animation: dot-pulse 1.4s infinite ease-in-out both;
  -webkit-animation: dot-pulse 1.4s infinite ease-in-out both;
}

.dots .pulse1 {
  animation-delay: -0.32s;
  -webkit-animation-delay: -0.32s;
}

.dots .pulse2 {
  animation-delay: -0.16s;
  -webkit-animation-delay: -0.16s;
}

@keyframes dot-pulse {
  0%, 80%, 100% {
    transform: scale(0);
    -webkit-transform: scale(0);
  }
  40% {
    transform: scale(1.0);
    -webkit-transform: scale(1.0);
  }
}

@-webkit-keyframes dot-pulse {
  0%, 80%, 100% { -webkit-transform: scale(0) }
  40% { -webkit-transform: scale(1.0) }
}
`;

renderCss();
renderHtml();