diff --git a/context7.json b/context7.json new file mode 100644 index 00000000..58724ac0 --- /dev/null +++ b/context7.json @@ -0,0 +1,4 @@ +{ + "url": "https://context7.com/bitbybit-dev/bitbybit", + "public_key": "pk_4NhKT0B4Cs69OWmP0yxwz" +} \ No newline at end of file diff --git a/docs/blog/2023-02-17-mixed-reality-cad.md b/docs/blog/2023-02-17-mixed-reality-cad.md index bf052542..e0cfaf8c 100644 --- a/docs/blog/2023-02-17-mixed-reality-cad.md +++ b/docs/blog/2023-02-17-mixed-reality-cad.md @@ -27,7 +27,7 @@ To showcase our application's capabilities, we have produced a video that depict src="https://www.youtube.com/embed/4rqxlJcS4eU" title="YouTube video player - Mixed Reality CAD Demo" frameborder="0" - allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/blog/2024-06-07-gaussian-splatting.md b/docs/blog/2024-06-07-gaussian-splatting.md index 561b2162..2cacd664 100644 --- a/docs/blog/2024-06-07-gaussian-splatting.md +++ b/docs/blog/2024-06-07-gaussian-splatting.md @@ -21,7 +21,7 @@ This method makes 3D models look remarkably smooth and realistic, often improvin In the video below, we demonstrate several 3D models scanned using this technique. You can also find these examples in our Public Projects section.
- +
### Potential Use Cases diff --git a/docs/blog/2024-07-29-3d-bits-app-for-shopify.md b/docs/blog/2024-07-29-3d-bits-app-for-shopify.md index e4013dbe..f29f94d9 100644 --- a/docs/blog/2024-07-29-3d-bits-app-for-shopify.md +++ b/docs/blog/2024-07-29-3d-bits-app-for-shopify.md @@ -19,7 +19,7 @@ Ready to get started? Visit our listing page! 3D Bits is now available for insta ➡️ **[Install 3D Bits App for Shopify](https://apps.shopify.com/3d-bits-1)**
- +
### Introducing 3D Bits diff --git a/docs/blog/2024-11-07-threejs-support.md b/docs/blog/2024-11-07-threejs-support.md index 834bc37b..1ae71ffb 100644 --- a/docs/blog/2024-11-07-threejs-support.md +++ b/docs/blog/2024-11-07-threejs-support.md @@ -25,7 +25,7 @@ Our main objective with these new releases is to make our CAD tools more versati This strategic move significantly broadens our reach and aligns perfectly with our vision of an open, adaptable CAD platform that meets the diverse needs of the global 3D developer community. Now, developers can leverage Bitbybit.dev's powerful CAD functionalities within their existing ThreeJS projects, or choose between ThreeJS and BabylonJS based on their project requirements.
- +
**See it in action with ThreeJS:** diff --git a/docs/blog/2025-01-01-update-3d-bits-app-shopify.md b/docs/blog/2025-01-01-update-3d-bits-app-shopify.md index 6044c890..02efd24c 100644 --- a/docs/blog/2025-01-01-update-3d-bits-app-shopify.md +++ b/docs/blog/2025-01-01-update-3d-bits-app-shopify.md @@ -52,7 +52,7 @@ For the best results with assets you own, we recommend uploading them to Shopify Here's a short tutorial that will walk you through all the steps involved to set up and use the BITBYBIT VIEWER block:
- +
### BITBYBIT PREVIEW Block @@ -68,7 +68,7 @@ The **BITBYBIT PREVIEW** block works with a single metafield where you can paste Here's a short tutorial that will walk you through all the steps involved to set up and use the BITBYBIT PREVIEW block:
- +
### Showcasing 3D Gaussian Splats diff --git a/docs/blog/2026-01-02-ironside-armour-use-case.mdx b/docs/blog/2026-01-02-ironside-armour-use-case.mdx index a2a07ca4..4b2c6b77 100644 --- a/docs/blog/2026-01-02-ironside-armour-use-case.mdx +++ b/docs/blog/2026-01-02-ironside-armour-use-case.mdx @@ -33,7 +33,7 @@ Traditional e-commerce approaches simply couldn't deliver this experience. That' src="https://www.youtube.com/embed/Bn74Amk2UJc" title="Ironside Armour Pro Power Rack configurator in action" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> @@ -86,7 +86,7 @@ We provided hands-on support and consulting during the initial setup. Ironside A src="https://www.youtube.com/embed/7mqd2FLlpcU" title="From STEP to GLTF - Convert PRO CAD 3D Models For 3D Bits Shopify App" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/blog/2026-01-06-playcanvas-support.md b/docs/blog/2026-01-06-playcanvas-support.md index ce79dd15..5554acc3 100644 --- a/docs/blog/2026-01-06-playcanvas-support.md +++ b/docs/blog/2026-01-06-playcanvas-support.md @@ -18,6 +18,19 @@ We are excited to announce the release of our new open-source NPM package and ru * GitHub: **[Bitbybit.dev Monorepo](https://github.com/bitbybit-dev/bitbybit)** * Documentation: **[PlayCanvas Integration Guide](/learn/npm-packages/playcanvas)** +Short demo of some of the Bitbybit projects rendered via PlayCanvas: +
+ +
+ ### Why PlayCanvas? PlayCanvas has established itself as a leading choice for web-based game development and interactive 3D experiences. Its entity-component architecture, visual editor, and exceptional runtime performance make it ideal for creating everything from games to product configurators. However, when it comes to precise CAD operations, parametric modeling, and industrial-grade geometry processing, developers have traditionally needed to look elsewhere. diff --git a/docs/learn/3d-bits/3d-assets/preparing-gltf.md b/docs/learn/3d-bits/3d-assets/preparing-gltf.md index 96912e5f..655f64f7 100644 --- a/docs/learn/3d-bits/3d-assets/preparing-gltf.md +++ b/docs/learn/3d-bits/3d-assets/preparing-gltf.md @@ -36,7 +36,7 @@ When you do triangulate, you’ll usually be able to choose how dense the mesh w src="https://www.youtube.com/embed/7mqd2FLlpcU" title="From STEP to GLTF - Convert PRO CAD 3D Models For 3D Bits Shopify App" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/3d-bits/intro.mdx b/docs/learn/3d-bits/intro.mdx index 9f704edd..4a4c2de7 100644 --- a/docs/learn/3d-bits/intro.mdx +++ b/docs/learn/3d-bits/intro.mdx @@ -37,7 +37,7 @@ Here's a quick look at 3D Bits in action: src="https://www.youtube.com/embed/y868HEQ8-lQ" title="3D Bits App For Shopify Demo" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-m_edia; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-m_edia; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/3d-bits/theme-app-extensions/bitbybit-preview.md b/docs/learn/3d-bits/theme-app-extensions/bitbybit-preview.md index 029e34e0..804a6a74 100644 --- a/docs/learn/3d-bits/theme-app-extensions/bitbybit-preview.md +++ b/docs/learn/3d-bits/theme-app-extensions/bitbybit-preview.md @@ -68,7 +68,7 @@ For a step-by-step visual guide on setting up the "3D Bits" app and its blocks, src="https://www.youtube.com/embed/9l7run2qy0Q?si=j8uSScxl6ncJaX81" title="3D Bits App For Shopify Fast Introduction" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/3d-bits/theme-app-extensions/bitbybit-viewer.md b/docs/learn/3d-bits/theme-app-extensions/bitbybit-viewer.md index c9addb4e..67c7d367 100644 --- a/docs/learn/3d-bits/theme-app-extensions/bitbybit-viewer.md +++ b/docs/learn/3d-bits/theme-app-extensions/bitbybit-viewer.md @@ -76,7 +76,7 @@ We highly recommend watching this tutorial where Matas explains how to use the V src="https://www.youtube.com/embed/7R6ueAHGFhg" title="3D Configurators On Shopify Product Pages with Bitbybit Viewer Editor And GLTF Assets (No Code)" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> @@ -124,7 +124,7 @@ For a comprehensive step-by-step guide on setting up and using the BITBYBIT VIEW src="https://www.youtube.com/embed/FcvQAVE1tDc" title="Tutorial Explains How To Use 3D Bits App For Shopify With BITBYBIT VIEWER Theme App Extension Block" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/3d-bits/tutorials/videos-tutorials/changing-materials.md b/docs/learn/3d-bits/tutorials/videos-tutorials/changing-materials.md index 87550d99..e9af4782 100644 --- a/docs/learn/3d-bits/tutorials/videos-tutorials/changing-materials.md +++ b/docs/learn/3d-bits/tutorials/videos-tutorials/changing-materials.md @@ -21,7 +21,7 @@ In this step-by-step tutorial, you’ll discover how to create, assign, and save src="https://www.youtube.com/embed/s00GpQp5Qmg" title="Change Materials, Colors, And Textures Of 3D Products On Shopify With 3D Bits App" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/3d-bits/tutorials/videos-tutorials/intro.md b/docs/learn/3d-bits/tutorials/videos-tutorials/intro.md index eb4d4b3f..26a840b9 100644 --- a/docs/learn/3d-bits/tutorials/videos-tutorials/intro.md +++ b/docs/learn/3d-bits/tutorials/videos-tutorials/intro.md @@ -32,7 +32,7 @@ For a fast overview of what "3D Bits" can do, check out this introductory video: src="https://www.youtube.com/embed/9l7run2qy0Q?si=j8uSScxl6ncJaX81" title="3D Bits App For Shopify Fast Introduction" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/3d-bits/tutorials/videos-tutorials/preview-3d-scans.md b/docs/learn/3d-bits/tutorials/videos-tutorials/preview-3d-scans.md index 046ec473..5978d1d0 100644 --- a/docs/learn/3d-bits/tutorials/videos-tutorials/preview-3d-scans.md +++ b/docs/learn/3d-bits/tutorials/videos-tutorials/preview-3d-scans.md @@ -34,7 +34,7 @@ Watch this step-by-step guide on how to configure and use the BITBYBIT PREVIEW b src="https://www.youtube.com/embed/xU5seV1NQ5o" title="Tutorial: Using 3D Bits App For Shopify With BITBYBIT PREVIEW Theme App Extension Block for 3D Scans" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/3d-bits/tutorials/videos-tutorials/product-3d-bike-scan.md b/docs/learn/3d-bits/tutorials/videos-tutorials/product-3d-bike-scan.md index c8a4050e..504bfc61 100644 --- a/docs/learn/3d-bits/tutorials/videos-tutorials/product-3d-bike-scan.md +++ b/docs/learn/3d-bits/tutorials/videos-tutorials/product-3d-bike-scan.md @@ -38,7 +38,7 @@ This video provides insights into working with 3D scans, particularly focusing o src="https://www.youtube.com/embed/f3rBNesXD1s?si=RXy1E2knDpdIm6Cz" title="Working with Gaussian Splatting 3D Scans for E-Commerce" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/3d-bits/tutorials/videos-tutorials/product-customizable-text.mdx b/docs/learn/3d-bits/tutorials/videos-tutorials/product-customizable-text.mdx index 05c20137..f434f318 100644 --- a/docs/learn/3d-bits/tutorials/videos-tutorials/product-customizable-text.mdx +++ b/docs/learn/3d-bits/tutorials/videos-tutorials/product-customizable-text.mdx @@ -36,7 +36,7 @@ This tutorial focuses on creating a Shopify product that features **customizable src="https://www.youtube.com/embed/MMURSZ47mJI?si=ec-iC2RxBJf2LYmV" title="Creating a Customizable 3D Text Product Configurator for Shopify" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/3d-bits/tutorials/videos-tutorials/product-laptop-holder.mdx b/docs/learn/3d-bits/tutorials/videos-tutorials/product-laptop-holder.mdx index 4ae80933..93013b72 100644 --- a/docs/learn/3d-bits/tutorials/videos-tutorials/product-laptop-holder.mdx +++ b/docs/learn/3d-bits/tutorials/videos-tutorials/product-laptop-holder.mdx @@ -39,7 +39,7 @@ You will learn how to: src="https://www.youtube.com/embed/_7CGezCqYrU?si=YRz9PerG67N3k_Xp" title="Building a 3D Laptop Holder Product Configurator for Shopify with TypeScript" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/3d-bits/tutorials/videos-tutorials/product-palm-table.mdx b/docs/learn/3d-bits/tutorials/videos-tutorials/product-palm-table.mdx index 061ae5b7..b102aaa3 100644 --- a/docs/learn/3d-bits/tutorials/videos-tutorials/product-palm-table.mdx +++ b/docs/learn/3d-bits/tutorials/videos-tutorials/product-palm-table.mdx @@ -37,7 +37,7 @@ This tutorial takes you a step further, demonstrating how more complex Bitbybit src="https://www.youtube.com/embed/dkOMbsQ10PI?si=ZZON7IZLSeYY2CXf" title="Building a Parametric 3D Palm Table Configurator for Shopify Tutorial" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/3d-bits/tutorials/videos-tutorials/runner-product-variants.md b/docs/learn/3d-bits/tutorials/videos-tutorials/runner-product-variants.md index 112737c3..fff700a0 100644 --- a/docs/learn/3d-bits/tutorials/videos-tutorials/runner-product-variants.md +++ b/docs/learn/3d-bits/tutorials/videos-tutorials/runner-product-variants.md @@ -26,7 +26,7 @@ We strongly encourage you to watch the video tutorial and follow along, repeatin src="https://www.youtube.com/embed/kP8_38k8fg8?si=83S5Qvcby15TAQkd" title="Creating 3D Product Variants on Shopify with 3D Bits App Tutorial" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/3d-bits/tutorials/videos-tutorials/set-up.md b/docs/learn/3d-bits/tutorials/videos-tutorials/set-up.md index fe3856af..6751b9b7 100644 --- a/docs/learn/3d-bits/tutorials/videos-tutorials/set-up.md +++ b/docs/learn/3d-bits/tutorials/videos-tutorials/set-up.md @@ -31,7 +31,7 @@ Completing these steps will lay the foundation for integrating powerful 3D exper src="https://www.youtube.com/embed/9jnDHb2MJ3M?si=YrwJe7sFm4_N2ZBH" title="Setting Up 3D Bits E-Commerce Solution for Shopify - Installation and Initial Configuration" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/3d-bits/tutorials/videos-tutorials/settings.md b/docs/learn/3d-bits/tutorials/videos-tutorials/settings.md index b3b06337..dfae2fd4 100644 --- a/docs/learn/3d-bits/tutorials/videos-tutorials/settings.md +++ b/docs/learn/3d-bits/tutorials/videos-tutorials/settings.md @@ -27,7 +27,7 @@ By the end of this tutorial, you should feel confident in configuring the "3D Bi src="https://www.youtube.com/embed/BAA-qDBxCAk?si=bdkTOh-Q9SDYdP_Q" title="Configuring Settings for the 3D Bits Shopify App" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/3d-bits/tutorials/videos-tutorials/step-to-gltf.md b/docs/learn/3d-bits/tutorials/videos-tutorials/step-to-gltf.md index 821122c6..09ff61a3 100644 --- a/docs/learn/3d-bits/tutorials/videos-tutorials/step-to-gltf.md +++ b/docs/learn/3d-bits/tutorials/videos-tutorials/step-to-gltf.md @@ -29,7 +29,7 @@ That’s why it’s essential to choose an efficient workflow for converting STE src="https://www.youtube.com/embed/7mqd2FLlpcU" title="From STEP to GLTF - Convert PRO CAD 3D Models For 3D Bits Shopify App" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/3d-bits/tutorials/videos-tutorials/viewer-no-code-3d-scan-configurators.md b/docs/learn/3d-bits/tutorials/videos-tutorials/viewer-no-code-3d-scan-configurators.md index 339d2a64..c1499a2f 100644 --- a/docs/learn/3d-bits/tutorials/videos-tutorials/viewer-no-code-3d-scan-configurators.md +++ b/docs/learn/3d-bits/tutorials/videos-tutorials/viewer-no-code-3d-scan-configurators.md @@ -30,7 +30,7 @@ Watch the video below to see how to use the Viewer Editor and the BITBYBIT VIEWE src="https://www.youtube.com/embed/B0N3l5Zl5fw" title="No-Code 3D Scanned Plant Configurators on Shopify with Bitbybit Viewer Editor and Gaussian Splats" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/3d-bits/tutorials/videos-tutorials/viewer-no-code-gltf-configurators.md b/docs/learn/3d-bits/tutorials/videos-tutorials/viewer-no-code-gltf-configurators.md index c1f194e4..8b2e530f 100644 --- a/docs/learn/3d-bits/tutorials/videos-tutorials/viewer-no-code-gltf-configurators.md +++ b/docs/learn/3d-bits/tutorials/videos-tutorials/viewer-no-code-gltf-configurators.md @@ -30,7 +30,7 @@ Watch Matas Ubarevičius demonstrate how to use the Viewer Editor and the BITBYB src="https://www.youtube.com/embed/7R6ueAHGFhg" title="No-Code 3D Configurators on Shopify Product Pages with Bitbybit Viewer Editor and GLTF Assets" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/3d-bits/tutorials/videos-tutorials/viewer-with-3d-scan.md b/docs/learn/3d-bits/tutorials/videos-tutorials/viewer-with-3d-scan.md index 6a3d94e1..0a4b6de0 100644 --- a/docs/learn/3d-bits/tutorials/videos-tutorials/viewer-with-3d-scan.md +++ b/docs/learn/3d-bits/tutorials/videos-tutorials/viewer-with-3d-scan.md @@ -31,7 +31,7 @@ You will learn how to: src="https://www.youtube.com/embed/FcvQAVE1tDc" title="Tutorial: Using 3D Bits App For Shopify With BITBYBIT VIEWER Theme App Extension Block for 3D Scans" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/getting-started/basics/scripts/search-public.md b/docs/learn/getting-started/basics/scripts/search-public.md index 90c8dab0..c486314e 100644 --- a/docs/learn/getting-started/basics/scripts/search-public.md +++ b/docs/learn/getting-started/basics/scripts/search-public.md @@ -41,7 +41,7 @@ Learn more about how the search feature works by watching this video tutorial: src="https://www.youtube.com/embed/m4cDaCQp23w" title="Video that introduces search feature" frameBorder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowFullScreen > \ No newline at end of file diff --git a/docs/learn/getting-started/configurators.mdx b/docs/learn/getting-started/configurators.mdx index 8eb61277..7f7820e7 100644 --- a/docs/learn/getting-started/configurators.mdx +++ b/docs/learn/getting-started/configurators.mdx @@ -44,7 +44,7 @@ The video below demonstrates one of our configurators. This particular one (Arab src="https://www.youtube.com/embed/lNOjdCV5sbI" title="Video of Arabic Archway Configurator" frameBorder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowFullScreen > diff --git a/docs/learn/getting-started/viewer-editor/intro.md b/docs/learn/getting-started/viewer-editor/intro.md index 030dcee5..2a4f7b2b 100644 --- a/docs/learn/getting-started/viewer-editor/intro.md +++ b/docs/learn/getting-started/viewer-editor/intro.md @@ -108,7 +108,7 @@ Learn how to build an interactive 3D chair configurator using the Viewer Editor src="https://www.youtube.com/embed/7R6ueAHGFhg" title="3D Configurators On Shopify Product Pages with Bitbybit Viewer Editor And GLTF Assets (No Code)" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/intro.md b/docs/learn/intro.md index 1f42679a..3c71afca 100644 --- a/docs/learn/intro.md +++ b/docs/learn/intro.md @@ -20,7 +20,7 @@ In this essential introduction to Bitbybit video Matas Ubarevičius explains the src="https://www.youtube.com/embed/noc6Rg6tMe0" title="Essential Introduction To BITBYBIT That Explains You The Most Important Aspects Of The 3D Platform" frameborder="0" - allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/npm-packages/babylonjs/advanced-parametric-3d-model.md b/docs/learn/npm-packages/babylonjs/advanced-parametric-3d-model.md index 01dff051..e6484932 100644 --- a/docs/learn/npm-packages/babylonjs/advanced-parametric-3d-model.md +++ b/docs/learn/npm-packages/babylonjs/advanced-parametric-3d-model.md @@ -24,7 +24,7 @@ You can see what the results of this app look like (rendered in Unreal Engine): src="https://www.youtube.com/embed/MbiELkXKCcY" title="From Web to Unreal Engine - Parametric Pavilion Design with Bitbybit running in THREEJS & BABYLONJS" frameborder="0" - allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/npm-packages/babylonjs/hex-house-concept.md b/docs/learn/npm-packages/babylonjs/hex-house-concept.md index 16d5c6bf..1396f809 100644 --- a/docs/learn/npm-packages/babylonjs/hex-house-concept.md +++ b/docs/learn/npm-packages/babylonjs/hex-house-concept.md @@ -24,7 +24,7 @@ In this related video tutorial you can see how the results of this app look like src="https://www.youtube.com/embed/Bgf-rAqAtdc" title="Unreal Engine 5 Using Assets From Bitbybit ThreeJS Configurator" frameborder="0" - allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/npm-packages/playcanvas/advanced-parametric-3d-model.md b/docs/learn/npm-packages/playcanvas/advanced-parametric-3d-model.md index d4999289..693f5adc 100644 --- a/docs/learn/npm-packages/playcanvas/advanced-parametric-3d-model.md +++ b/docs/learn/npm-packages/playcanvas/advanced-parametric-3d-model.md @@ -28,7 +28,7 @@ You can see what the results of this app look like (rendered in Unreal Engine): src="https://www.youtube.com/embed/MbiELkXKCcY" title="From Web to Unreal Engine - Parametric Pavilion Design with Bitbybit running in THREEJS & BABYLONJS" frameborder="0" - allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/npm-packages/playcanvas/hex-house-concept.md b/docs/learn/npm-packages/playcanvas/hex-house-concept.md index 7cc83b38..384e6da1 100644 --- a/docs/learn/npm-packages/playcanvas/hex-house-concept.md +++ b/docs/learn/npm-packages/playcanvas/hex-house-concept.md @@ -28,7 +28,7 @@ In this related video tutorial you can see how the results of this app look like src="https://www.youtube.com/embed/Bgf-rAqAtdc" title="Unreal Engine 5 Using Assets From Bitbybit ThreeJS Configurator" frameborder="0" - allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/npm-packages/threejs/advanced-parametric-3d-model.md b/docs/learn/npm-packages/threejs/advanced-parametric-3d-model.md index 190a8f0e..d5fbda49 100644 --- a/docs/learn/npm-packages/threejs/advanced-parametric-3d-model.md +++ b/docs/learn/npm-packages/threejs/advanced-parametric-3d-model.md @@ -24,7 +24,7 @@ You can see what the results of this app look like (rendered in Unreal Engine): src="https://www.youtube.com/embed/MbiELkXKCcY" title="From Web to Unreal Engine - Parametric Pavilion Design with Bitbybit running in THREEJS & BABYLONJS" frameborder="0" - allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/npm-packages/threejs/hex-house-concept.md b/docs/learn/npm-packages/threejs/hex-house-concept.md index 1fc267fd..26ec9fcd 100644 --- a/docs/learn/npm-packages/threejs/hex-house-concept.md +++ b/docs/learn/npm-packages/threejs/hex-house-concept.md @@ -25,7 +25,7 @@ In this related video tutorial you can see how the results of this app look like src="https://www.youtube.com/embed/Bgf-rAqAtdc" title="Unreal Engine 5 Using Assets From Bitbybit ThreeJS Configurator" frameborder="0" - allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/runners/engines/_category_.json b/docs/learn/runners/engines/_category_.json index 8e8dd647..923fc6f9 100644 --- a/docs/learn/runners/engines/_category_.json +++ b/docs/learn/runners/engines/_category_.json @@ -1,6 +1,6 @@ { "label": "Engines", - "position": 10, + "position": 3, "link": { "type": "generated-index", "description": "Learn how to use Bitbybit runners with different 3D engines - PlayCanvas, Three.js, and Babylon.js." diff --git a/docs/learn/runners/engines/playcanvas/text-3d-on-face.mdx b/docs/learn/runners/engines/playcanvas/text-3d-on-face.mdx new file mode 100644 index 00000000..a7c85b09 --- /dev/null +++ b/docs/learn/runners/engines/playcanvas/text-3d-on-face.mdx @@ -0,0 +1,436 @@ +--- +sidebar_position: 3 +title: PlayCanvas 3D Text on Face Example +description: Learn how to create 3D text on a parametric surface using the Bitbybit PlayCanvas runner with advanced lighting and materials +--- + +import BitByBitRenderCanvas from '@site/src/components/BitByBitRenderCanvas'; + +# PlayCanvas 3D Text on Face Example + +This advanced example demonstrates how to create **3D text on a parametric lofted surface** using the Bitbybit PlayCanvas runner. It showcases custom materials, enhanced lighting setup, orbit camera controls, and professional rendering techniques. + +## Live Example + + + +## Key Features + +This example demonstrates several advanced techniques: + +- **3D Text on Parametric Surface** - Creating text that follows the curvature of a lofted face +- **Custom Materials** - Metallic materials with specular highlights using `faceMaterial` option +- **Multi-Light Setup** - Professional 5-point lighting with shadows +- **Orbit Camera Controls** - Interactive camera using Bitbybit's orbit camera API +- **Sharp Hardware Scaling** - High-DPI rendering using `maxPixelRatio` +- **Edge Shadow Control** - Disabling shadows on edge entities for cleaner rendering + +## Complete Example + +```html + + + + Bitbybit Runner PlayCanvas Full Example 3D Text On Face + + + + + + + + + +
+ +
+ + +``` + +## Key Techniques Explained + +### Sharp Hardware Scaling + +After initializing the runner, set the device pixel ratio for crisp rendering on high-DPI displays: + +```javascript +app.graphicsDevice.maxPixelRatio = window.devicePixelRatio; +app.resizeCanvas(); +``` + +### Orbit Camera Controls + +Use Bitbybit's built-in orbit camera for interactive 3D navigation: + +```javascript +const cameraOptions = new Bit.Inputs.PlayCanvasCamera.OrbitCameraDto(); +cameraOptions.distance = 45; +cameraOptions.pitch = -20; +cameraOptions.yaw = 45; +cameraOptions.focusEntity = camera; +bitbybit.playcanvas.camera.orbitCamera.create(cameraOptions); +``` + +### Custom Materials with faceMaterial + +Pass custom PlayCanvas `StandardMaterial` objects to the draw options: + +```javascript +const surfaceMaterial = new pc.StandardMaterial(); +surfaceMaterial.diffuse = new pc.Color(1, 0.3, 0); +surfaceMaterial.metalness = 0.7; +surfaceMaterial.gloss = 0.9; +surfaceMaterial.useMetalness = true; +surfaceMaterial.update(); + +const loftDrawOpt = new Bit.Inputs.Draw.DrawOcctShapeOptions(); +loftDrawOpt.faceMaterial = surfaceMaterial; +``` + +### 3D Text on Parametric Face + +Create text that follows the surface curvature: + +```javascript +const txtOpt = new Bit.Advanced.Text3D.Text3DFaceDto(); +txtOpt.text = 'PlayCanvas'; +txtOpt.face = loftFace; +txtOpt.fontSize = 0.18; +txtOpt.rotation = -45; +txtOpt.height = -1; // Negative for extruding downward + +const text = await bitbybit.advanced.text3d.createTextOnFace(txtOpt); +``` + +### Disabling Edge Shadows + +Edges are the third child entity in the returned group - disable their shadows for cleaner visuals: + +```javascript +function disableEdgeShadows(group) { + if (group && group.children && group.children[2]) { + const edgeEntity = group.children[2]; + if (edgeEntity.render) { + edgeEntity.render.castShadows = false; + } + } +} +``` + +## GitHub Source + +View the full source code on GitHub: [PlayCanvas Text 3D on Face Example](https://github.com/bitbybit-dev/bitbybit/tree/master/examples/runner/playcanvas/full/text-3d-on-face) diff --git a/docs/learn/runners/intro-blockly.mdx b/docs/learn/runners/intro-blockly.mdx index 3fa38f6d..48e3e04b 100644 --- a/docs/learn/runners/intro-blockly.mdx +++ b/docs/learn/runners/intro-blockly.mdx @@ -27,7 +27,7 @@ The use of a simple OCCT cube geometry is intentional. The main goal here is to src="https://www.youtube.com/embed/NVT-17RTwUo" title="Introduction To Bitbybit Runner With Blockly" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/runners/intro-rete.mdx b/docs/learn/runners/intro-rete.mdx index 323f423e..592a86d4 100644 --- a/docs/learn/runners/intro-rete.mdx +++ b/docs/learn/runners/intro-rete.mdx @@ -30,7 +30,7 @@ We will guide you through: src="https://www.youtube.com/embed/HtrgvYZK06w" title="Introduction To Bitbybit Runner" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/runners/intro-typescript.mdx b/docs/learn/runners/intro-typescript.mdx index c78720c9..ac365a39 100644 --- a/docs/learn/runners/intro-typescript.mdx +++ b/docs/learn/runners/intro-typescript.mdx @@ -25,7 +25,7 @@ The focus is on a simple OCCT cube geometry. The primary goal is to illustrate h src="https://www.youtube.com/embed/7WyI4EtnlKY" title="Introduction To Bitbybit Runner With TypeScript" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/runners/intro.mdx b/docs/learn/runners/intro.mdx index 956b4394..21fd3506 100644 --- a/docs/learn/runners/intro.mdx +++ b/docs/learn/runners/intro.mdx @@ -23,7 +23,7 @@ This section will guide you through understanding and utilizing the Bitbybit Run src="https://www.youtube.com/embed/YK0pslfTseY" title="Bitbybit Runner In Action" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/runners/table-configurator-blockly.mdx b/docs/learn/runners/table-configurator-blockly.mdx index 2191030a..f4c7b051 100644 --- a/docs/learn/runners/table-configurator-blockly.mdx +++ b/docs/learn/runners/table-configurator-blockly.mdx @@ -25,7 +25,7 @@ Matas Ubarevičius will demonstrate setting up the basic HTML, CSS, and JavaScri src="https://www.youtube.com/embed/i_-ksEaY4Tg" title="3D Table Configurator Tutorial with Blockly and Bitbybit Runner" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/runners/table-configurator-rete.mdx b/docs/learn/runners/table-configurator-rete.mdx index b6f9a140..0b42f2ef 100644 --- a/docs/learn/runners/table-configurator-rete.mdx +++ b/docs/learn/runners/table-configurator-rete.mdx @@ -25,7 +25,7 @@ Matas Ubarevičius will demonstrate setting up the basic HTML, CSS, and JavaScri src="https://www.youtube.com/embed/W5gLQTMWpvY" title="3D Table Configurator Tutorial with Rete and Bitbybit Runner" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/learn/runners/table-configurator-typescript.mdx b/docs/learn/runners/table-configurator-typescript.mdx index 1b7369b3..9bee2a17 100644 --- a/docs/learn/runners/table-configurator-typescript.mdx +++ b/docs/learn/runners/table-configurator-typescript.mdx @@ -30,7 +30,7 @@ This free lecture is designed for a wide audience, from beginners looking to div src="https://www.youtube.com/embed/Gzs0Bw5dM1M" title="3D Table Configurator Tutorial with TypeScript and Bitbybit Runner" frameborder="0" - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" allowfullscreen> diff --git a/docs/src/pages/index.module.css b/docs/src/pages/index.module.css index 8a61d36a..9cce9cd8 100644 --- a/docs/src/pages/index.module.css +++ b/docs/src/pages/index.module.css @@ -282,12 +282,13 @@ background-clip: text; -webkit-text-fill-color: transparent; position: relative; + padding-bottom: -0.15em; } .highlight::after { content: ''; position: absolute; - bottom: -4px; + bottom: 0; left: 0; right: 0; height: 4px; diff --git a/examples/runner/playcanvas/full/text-3d-on-face/index.html b/examples/runner/playcanvas/full/text-3d-on-face/index.html new file mode 100644 index 00000000..68a5af06 --- /dev/null +++ b/examples/runner/playcanvas/full/text-3d-on-face/index.html @@ -0,0 +1,339 @@ + + + + Bitbybit Runner PlayCanvas Full Example 3D Text On Face + + + + + + + + + +
+ +
+ + diff --git a/examples/vite/playcanvas/hex-house-concept/src/helpers/create-shape.ts b/examples/vite/playcanvas/hex-house-concept/src/helpers/create-shape.ts index 49d26fca..0c2d7352 100644 --- a/examples/vite/playcanvas/hex-house-concept/src/helpers/create-shape.ts +++ b/examples/vite/playcanvas/hex-house-concept/src/helpers/create-shape.ts @@ -1,322 +1,307 @@ import type { BitByBitBase } from "@bitbybit-dev/playcanvas"; import { Inputs } from "@bitbybit-dev/playcanvas"; -import type { Entity, StandardMaterial } from "playcanvas"; +import type { Entity } from "playcanvas"; import type { Current, Model } from "../models"; -const applyDepthBias = (entity: Entity, depthBias: number) => { - if (entity.render) { - entity.render.meshInstances.forEach((mi) => { - const mat = mi.material as StandardMaterial; - if (mat) { - mat.depthBias = depthBias; - mat.slopeDepthBias = depthBias; - mat.update(); - } - }); - } - entity.children.forEach((child) => applyDepthBias(child as Entity, depthBias)); -}; - export const createShape = async ( - bitbybit: BitByBitBase | undefined, - scene: Entity | undefined, - model: Model, - shapesToClean: Inputs.OCCT.TopoDSShapePointer[], - current: Current + bitbybit: BitByBitBase | undefined, + scene: Entity | undefined, + model: Model, + shapesToClean: Inputs.OCCT.TopoDSShapePointer[], + current: Current ) => { - if (scene && bitbybit) { - if (shapesToClean.length > 0) { - await bitbybit.occt.deleteShapes({ shapes: shapesToClean }); - } - if (shapesToClean.length > 0) { - await bitbybit.occt.deleteShapes({ shapes: shapesToClean }); + if (scene && bitbybit) { + if (shapesToClean.length > 0) { + await bitbybit.occt.deleteShapes({ shapes: shapesToClean }); + } + if (shapesToClean.length > 0) { + await bitbybit.occt.deleteShapes({ shapes: shapesToClean }); + } + + shapesToClean = []; + type Point3 = Inputs.Base.Point3; + const sd = { + groundCrv: [ + [-15, 0.1, -4.5], + [0, 0.1, -3.5], + [13, 0.1, -4.5], + ] as Point3[], + groundMid: [ + [-16, 0.1, 0], + [14, 0.1, 0], + ] as Point3[], + firstCrv: [ + [-12, 0, -5], + [-7, 0, -2], + [0, 0, -4], + [2, 0, -3], + [12, 0, -3], + ] as Point3[], + secondCrv: [ + [-14, 2, -8], + [-7, 1.3, -3], + [0, 1.8, -5.8], + [2, 2, -5], + [14, 1.5, -4], + ] as Point3[], + midCrv: [ + [-18, 4, 0], + [-7, 5, 0], + [0, 3.7, 0], + [2, 3.7, 0], + [12, 8, 0], + ] as Point3[], + }; + + const { shapes, transforms, operations } = bitbybit.occt; + const { face } = shapes; + + const intOptions = new Inputs.OCCT.InterpolationDto(); + intOptions.points = sd.groundCrv; + const groundCrv = await shapes.wire.interpolatePoints(intOptions); + shapesToClean.push(groundCrv); + + const mirrorOptions = + new Inputs.OCCT.MirrorAlongNormalDto(); + mirrorOptions.normal = [0, 0, 1]; + mirrorOptions.shape = groundCrv; + const groundCrvMir = await transforms.mirrorAlongNormal(mirrorOptions); + shapesToClean.push(groundCrvMir); + + intOptions.points = sd.groundMid; + const groundMid = await shapes.wire.interpolatePoints(intOptions); + shapesToClean.push(groundMid); + + intOptions.points = sd.firstCrv; + const firstCrv = await shapes.wire.interpolatePoints(intOptions); + mirrorOptions.shape = firstCrv; + const firstCrvMir = await transforms.mirrorAlongNormal(mirrorOptions); + shapesToClean.push(firstCrv); + shapesToClean.push(firstCrvMir); + + intOptions.points = sd.secondCrv; + const secondCrv = await shapes.wire.interpolatePoints(intOptions); + mirrorOptions.shape = secondCrv; + const secondCrvMir = await transforms.mirrorAlongNormal(mirrorOptions); + shapesToClean.push(secondCrv); + shapesToClean.push(secondCrvMir); + + intOptions.points = sd.midCrv; + const midCrv = await shapes.wire.interpolatePoints(intOptions); + shapesToClean.push(midCrv); + + const loftOptions = + new Inputs.OCCT.LoftAdvancedDto(); + loftOptions.shapes = [ + midCrv, + secondCrv, + firstCrv, + groundCrv, + groundMid, + groundCrvMir, + firstCrvMir, + secondCrvMir, + midCrv, + ]; + loftOptions.straight = true; + const loft = await operations.loftAdvanced(loftOptions); + shapesToClean.push(loft); + + const faceRoof = await face.getFace({ shape: loft, index: 0 }); + const faceWall = await face.getFace({ shape: loft, index: 1 }); + shapesToClean.push(faceRoof); + shapesToClean.push(faceWall); + + const roof = await createHexagonsRoof( + faceRoof, + model.uHex, + model.vHex, + bitbybit + ); + const wall = await createHexagonsWalls( + faceWall, + model.uHex, + Math.ceil(model.vHex / 2), + bitbybit + ); + const wallExtrude = await operations.extrude({ + shape: wall, + direction: [0, 0, -0.2], + }); + const mirroredRoofPromises = roof.map((r) => { + mirrorOptions.shape = r; + return transforms.mirrorAlongNormal(mirrorOptions); + }); + + mirrorOptions.shape = wallExtrude; + const mirroredWall = await transforms.mirrorAlongNormal(mirrorOptions); + + const mirroredRoof = await Promise.all(mirroredRoofPromises); + + const comp = await shapes.compound.makeCompound({ + shapes: [...roof, ...mirroredRoof, wallExtrude, mirroredWall], + }); + shapesToClean.push(comp); + + const finalShape = comp; + + const compRoof1 = await shapes.compound.makeCompound({ + shapes: [roof[0], mirroredRoof[0], wallExtrude, mirroredWall], + }); + const compRoof2 = await shapes.compound.makeCompound({ + shapes: [roof[1], mirroredRoof[1]], + }); + const compRoof3 = await shapes.compound.makeCompound({ + shapes: [roof[2], mirroredRoof[2]], + }); + + const options = new Inputs.Draw.DrawOcctShapeOptions(); + options.precision = 0.06; + options.drawEdges = model.drawEdges; + options.drawFaces = model.drawFaces; + options.edgeColour = "#130301"; + options.faceColour = model.color; + options.drawTwoSided = false; + + const groupRoof1 = await bitbybit.draw.drawAnyAsync({ + entity: compRoof1, + options, + }); + options.edgeColour = "#000000"; + options.faceColour = "#ff4800"; + + const groupRoof2 = await bitbybit.draw.drawAnyAsync({ + entity: compRoof2, + options, + }); + + options.faceColour = "#ff9100"; + + const groupRoof3 = await bitbybit.draw.drawAnyAsync({ + entity: compRoof3, + options, + }); + + current.groups = [groupRoof1, groupRoof2, groupRoof3]; + + current.groups.forEach((group) => { + // Disable shadow casting on edge entities (third child in group structure) + if (group.children && group.children[1]) { + const edgeEntity = group.children[1] as Entity; + if (edgeEntity.render) { + edgeEntity.render.castShadows = false; + } + } + }); + + return finalShape; } +}; - shapesToClean = []; - type Point3 = Inputs.Base.Point3; - const sd = { - groundCrv: [ - [-15, 0.1, -4.5], - [0, 0.1, -3.5], - [13, 0.1, -4.5], - ] as Point3[], - groundMid: [ - [-16, 0.1, 0], - [14, 0.1, 0], - ] as Point3[], - firstCrv: [ - [-12, 0, -5], - [-7, 0, -2], - [0, 0, -4], - [2, 0, -3], - [12, 0, -3], - ] as Point3[], - secondCrv: [ - [-14, 2, -8], - [-7, 1.3, -3], - [0, 1.8, -5.8], - [2, 2, -5], - [14, 1.5, -4], - ] as Point3[], - midCrv: [ - [-18, 4, 0], - [-7, 5, 0], - [0, 3.7, 0], - [2, 3.7, 0], - [12, 8, 0], - ] as Point3[], - }; - - const { shapes, transforms, operations } = bitbybit.occt; +async function createHexagonsWalls( + f: Inputs.OCCT.TopoDSFacePointer, + nrHexagonsU: number, + nrHexagonsV: number, + bitbybit: BitByBitBase +) { + const { shapes } = bitbybit.occt; const { face } = shapes; - const intOptions = new Inputs.OCCT.InterpolationDto(); - intOptions.points = sd.groundCrv; - const groundCrv = await shapes.wire.interpolatePoints(intOptions); - shapesToClean.push(groundCrv); - - const mirrorOptions = - new Inputs.OCCT.MirrorAlongNormalDto(); - mirrorOptions.normal = [0, 0, 1]; - mirrorOptions.shape = groundCrv; - const groundCrvMir = await transforms.mirrorAlongNormal(mirrorOptions); - shapesToClean.push(groundCrvMir); - - intOptions.points = sd.groundMid; - const groundMid = await shapes.wire.interpolatePoints(intOptions); - shapesToClean.push(groundMid); - - intOptions.points = sd.firstCrv; - const firstCrv = await shapes.wire.interpolatePoints(intOptions); - mirrorOptions.shape = firstCrv; - const firstCrvMir = await transforms.mirrorAlongNormal(mirrorOptions); - shapesToClean.push(firstCrv); - shapesToClean.push(firstCrvMir); - - intOptions.points = sd.secondCrv; - const secondCrv = await shapes.wire.interpolatePoints(intOptions); - mirrorOptions.shape = secondCrv; - const secondCrvMir = await transforms.mirrorAlongNormal(mirrorOptions); - shapesToClean.push(secondCrv); - shapesToClean.push(secondCrvMir); - - intOptions.points = sd.midCrv; - const midCrv = await shapes.wire.interpolatePoints(intOptions); - shapesToClean.push(midCrv); - - const loftOptions = - new Inputs.OCCT.LoftAdvancedDto(); - loftOptions.shapes = [ - midCrv, - secondCrv, - firstCrv, - groundCrv, - groundMid, - groundCrvMir, - firstCrvMir, - secondCrvMir, - midCrv, - ]; - loftOptions.straight = true; - const loft = await operations.loftAdvanced(loftOptions); - shapesToClean.push(loft); - - const faceRoof = await face.getFace({ shape: loft, index: 0 }); - const faceWall = await face.getFace({ shape: loft, index: 1 }); - shapesToClean.push(faceRoof); - shapesToClean.push(faceWall); - - const roof = await createHexagonsRoof( - faceRoof, - model.uHex, - model.vHex, - bitbybit - ); - const wall = await createHexagonsWalls( - faceWall, - model.uHex, - Math.ceil(model.vHex / 2), - bitbybit - ); - const wallExtrude = await operations.extrude({ - shape: wall, - direction: [0, 0, -0.2], - }); - const mirroredRoofPromises = roof.map((r) => { - mirrorOptions.shape = r; - return transforms.mirrorAlongNormal(mirrorOptions); - }); - - mirrorOptions.shape = wallExtrude; - const mirroredWall = await transforms.mirrorAlongNormal(mirrorOptions); - - const mirroredRoof = await Promise.all(mirroredRoofPromises); + const hexSubdivisionOptions = + new Inputs.OCCT.FaceSubdivideToHexagonHolesDto(); + hexSubdivisionOptions.shape = f; + hexSubdivisionOptions.nrHexagonsU = nrHexagonsU; + hexSubdivisionOptions.nrHexagonsV = nrHexagonsV; + hexSubdivisionOptions.scalePatternU = [0.8, 0.5, 0.5, 0.3]; + hexSubdivisionOptions.scalePatternV = [0.8, 0.5, 0.5, 0.3]; + hexSubdivisionOptions.offsetFromBorderV = 0.1; + hexSubdivisionOptions.offsetFromBorderV = 0.1; + hexSubdivisionOptions.flatU = false; + hexSubdivisionOptions.inclusionPattern = [true, true, true, false]; + const sub = await face.subdivideToHexagonHoles(hexSubdivisionOptions); + + return sub[0]; +} - const comp = await shapes.compound.makeCompound({ - shapes: [...roof, ...mirroredRoof, wallExtrude, mirroredWall], +async function createHexagonsRoof( + f: Inputs.OCCT.TopoDSFacePointer, + nrHexagonsU: number, + nrHexagonsV: number, + bitbybit: BitByBitBase +) { + const { shapes, operations } = bitbybit.occt; + const { face, wire } = shapes; + + const hexSubdivisionOptions = + new Inputs.OCCT.FaceSubdivideToHexagonWiresDto(); + hexSubdivisionOptions.shape = f; + hexSubdivisionOptions.nrHexagonsU = nrHexagonsU; + hexSubdivisionOptions.nrHexagonsV = nrHexagonsV; + hexSubdivisionOptions.scalePatternU = [0.8, 0.5, 0.1, 0.1, 0.1]; + hexSubdivisionOptions.scalePatternV = [0.8, 0.5, 0.1, 0.1, 0.1]; + hexSubdivisionOptions.flatU = false; + hexSubdivisionOptions.inclusionPattern = [true, true, true, false]; + const sub = await face.subdivideToHexagonWires(hexSubdivisionOptions); + + const hexSubdivisionOptions2 = + new Inputs.OCCT.FaceSubdivideToHexagonWiresDto(); + hexSubdivisionOptions2.shape = f; + hexSubdivisionOptions2.flatU = false; + hexSubdivisionOptions2.nrHexagonsU = nrHexagonsU; + hexSubdivisionOptions2.nrHexagonsV = nrHexagonsV; + hexSubdivisionOptions2.inclusionPattern = [true, true, true, false]; + const sub2 = await face.subdivideToHexagonWires(hexSubdivisionOptions2); + + const promisesWires = sub.map((s) => wire.reversedWire({ shape: s })); + const revSub = await Promise.all(promisesWires); + + const promiseFaces = revSub.map((s1, index) => { + const s2 = sub2[index]; + return face.createFaceFromWires({ shapes: [s2, s1], planar: false }); }); - shapesToClean.push(comp); - const finalShape = comp; + const faces = await Promise.all(promiseFaces); - const compRoof1 = await shapes.compound.makeCompound({ - shapes: [roof[0], mirroredRoof[0], wallExtrude, mirroredWall], - }); - const compRoof2 = await shapes.compound.makeCompound({ - shapes: [roof[1], mirroredRoof[1]], - }); - const compRoof3 = await shapes.compound.makeCompound({ - shapes: [roof[2], mirroredRoof[2]], - }); + const heightPattern = [0.11, 0.1, 0.1]; + let heightPatternIndex = 0; - const options = new Inputs.Draw.DrawOcctShapeOptions(); - options.precision = 0.19; - options.drawEdges = model.drawEdges; - options.drawFaces = model.drawFaces; - options.edgeColour = "#000000"; - options.faceColour = model.color; - options.drawTwoSided = false; - - const groupRoof1 = await bitbybit.draw.drawAnyAsync({ - entity: compRoof1, - options, - }); - - options.faceColour = "#ff4800ff"; + const group1Promises: Promise[] = []; + const group2Promises: Promise[] = []; + const group3Promises: Promise[] = []; - const groupRoof2 = await bitbybit.draw.drawAnyAsync({ - entity: compRoof2, - options, + faces.forEach((face) => { + const height = heightPattern[heightPatternIndex]; + if (heightPatternIndex === heightPattern.length - 1) { + heightPatternIndex = 0; + } else { + heightPatternIndex++; + } + const thick = operations.makeThickSolidSimple({ + shape: face, + offset: height, + }); + if (heightPatternIndex === 0) { + group1Promises.push(thick); + } else if (heightPatternIndex === 1) { + group2Promises.push(thick); + } else if (heightPatternIndex === 2) { + group3Promises.push(thick); + } }); - options.faceColour = "#ff9100ff"; + const group1 = await Promise.all(group1Promises); + const group2 = await Promise.all(group2Promises); + const group3 = await Promise.all(group3Promises); - const groupRoof3 = await bitbybit.draw.drawAnyAsync({ - entity: compRoof3, - options, + const compound1 = await shapes.compound.makeCompound({ + shapes: group1, }); - - current.groups = [groupRoof1, groupRoof2, groupRoof3]; - - current.groups.forEach((group) => { - applyDepthBias(group, 0.1); - // Disable shadow casting on edge entities (third child in group structure) - if (group.children && group.children[2]) { - const edgeEntity = group.children[2] as Entity; - if (edgeEntity.render) { - edgeEntity.render.castShadows = false; - } - } + const compound2 = await shapes.compound.makeCompound({ + shapes: group2, }); - - return finalShape; - } -}; - -async function createHexagonsWalls( - f: Inputs.OCCT.TopoDSFacePointer, - nrHexagonsU: number, - nrHexagonsV: number, - bitbybit: BitByBitBase -) { - const { shapes } = bitbybit.occt; - const { face } = shapes; - - const hexSubdivisionOptions = - new Inputs.OCCT.FaceSubdivideToHexagonHolesDto(); - hexSubdivisionOptions.shape = f; - hexSubdivisionOptions.nrHexagonsU = nrHexagonsU; - hexSubdivisionOptions.nrHexagonsV = nrHexagonsV; - hexSubdivisionOptions.scalePatternU = [0.8, 0.5, 0.5, 0.3]; - hexSubdivisionOptions.scalePatternV = [0.8, 0.5, 0.5, 0.3]; - hexSubdivisionOptions.offsetFromBorderV = 0.1; - hexSubdivisionOptions.offsetFromBorderV = 0.1; - hexSubdivisionOptions.flatU = false; - hexSubdivisionOptions.inclusionPattern = [true, true, true, false]; - const sub = await face.subdivideToHexagonHoles(hexSubdivisionOptions); - - return sub[0]; -} - -async function createHexagonsRoof( - f: Inputs.OCCT.TopoDSFacePointer, - nrHexagonsU: number, - nrHexagonsV: number, - bitbybit: BitByBitBase -) { - const { shapes, operations } = bitbybit.occt; - const { face, wire } = shapes; - - const hexSubdivisionOptions = - new Inputs.OCCT.FaceSubdivideToHexagonWiresDto(); - hexSubdivisionOptions.shape = f; - hexSubdivisionOptions.nrHexagonsU = nrHexagonsU; - hexSubdivisionOptions.nrHexagonsV = nrHexagonsV; - hexSubdivisionOptions.scalePatternU = [0.8, 0.5, 0.1, 0.1, 0.1]; - hexSubdivisionOptions.scalePatternV = [0.8, 0.5, 0.1, 0.1, 0.1]; - hexSubdivisionOptions.flatU = false; - hexSubdivisionOptions.inclusionPattern = [true, true, true, false]; - const sub = await face.subdivideToHexagonWires(hexSubdivisionOptions); - - const hexSubdivisionOptions2 = - new Inputs.OCCT.FaceSubdivideToHexagonWiresDto(); - hexSubdivisionOptions2.shape = f; - hexSubdivisionOptions2.flatU = false; - hexSubdivisionOptions2.nrHexagonsU = nrHexagonsU; - hexSubdivisionOptions2.nrHexagonsV = nrHexagonsV; - hexSubdivisionOptions2.inclusionPattern = [true, true, true, false]; - const sub2 = await face.subdivideToHexagonWires(hexSubdivisionOptions2); - - const promisesWires = sub.map((s) => wire.reversedWire({ shape: s })); - const revSub = await Promise.all(promisesWires); - - const promiseFaces = revSub.map((s1, index) => { - const s2 = sub2[index]; - return face.createFaceFromWires({ shapes: [s2, s1], planar: false }); - }); - - const faces = await Promise.all(promiseFaces); - - const heightPattern = [0.11, 0.1, 0.1]; - let heightPatternIndex = 0; - - const group1Promises: Promise[] = []; - const group2Promises: Promise[] = []; - const group3Promises: Promise[] = []; - - faces.forEach((face) => { - const height = heightPattern[heightPatternIndex]; - if (heightPatternIndex === heightPattern.length - 1) { - heightPatternIndex = 0; - } else { - heightPatternIndex++; - } - const thick = operations.makeThickSolidSimple({ - shape: face, - offset: height, + const compound3 = await shapes.compound.makeCompound({ + shapes: group3, }); - if (heightPatternIndex === 0) { - group1Promises.push(thick); - } else if (heightPatternIndex === 1) { - group2Promises.push(thick); - } else if (heightPatternIndex === 2) { - group3Promises.push(thick); - } - }); - - const group1 = await Promise.all(group1Promises); - const group2 = await Promise.all(group2Promises); - const group3 = await Promise.all(group3Promises); - - const compound1 = await shapes.compound.makeCompound({ - shapes: group1, - }); - const compound2 = await shapes.compound.makeCompound({ - shapes: group2, - }); - const compound3 = await shapes.compound.makeCompound({ - shapes: group3, - }); - - return [compound1, compound2, compound3]; + + return [compound1, compound2, compound3]; } diff --git a/examples/vite/playcanvas/hex-house-concept/src/helpers/init-playcanvas.ts b/examples/vite/playcanvas/hex-house-concept/src/helpers/init-playcanvas.ts index 539bba19..3488dd59 100644 --- a/examples/vite/playcanvas/hex-house-concept/src/helpers/init-playcanvas.ts +++ b/examples/vite/playcanvas/hex-house-concept/src/helpers/init-playcanvas.ts @@ -19,6 +19,7 @@ export function initPlayCanvas() { graphicsDeviceOptions: { antialias: true, alpha: false, + devicePixelRatio: 0.5, }, mouse: new Mouse(canvas), touch: new TouchDevice(canvas), @@ -76,7 +77,7 @@ export function createDirLightsAndGround(scene: Entity, current: Current) { intensity: 0.8, castShadows: true, shadowDistance: 40, - shadowResolution: 3048, + shadowResolution: 4000, shadowBias: 0.2, normalOffsetBias: 0.02, shadowType: 1, @@ -91,7 +92,7 @@ export function createDirLightsAndGround(scene: Entity, current: Current) { type: "plane", }); ground.setLocalScale(74, 1, 74); - ground.setPosition(0, 0, 0); + ground.setPosition(0, -0.01, 0); // Create material for ground const material = new StandardMaterial();