From c93e7c1998ab277ca2fcdb6604654ae05755cfe2 Mon Sep 17 00:00:00 2001 From: Banyapon Poolsawas Date: Tue, 6 Aug 2024 10:22:14 +0700 Subject: [PATCH] First Commit with all script Export GLB, favcion, vr controller --- aframe_exporter/LICENSE | 23 ++++++++++++ aframe_exporter/README.md | 52 +++++++++++++++++++++++++++ aframe_exporter/__init__.py | 27 +++++++++++++++ aframe_exporter/aframe_exporter.py | 54 +++++++++++++++++++++++++++++ aframe_exporter/icons/favicon.ico | Bin 0 -> 15406 bytes 5 files changed, 156 insertions(+) create mode 100644 aframe_exporter/LICENSE create mode 100644 aframe_exporter/README.md create mode 100644 aframe_exporter/__init__.py create mode 100644 aframe_exporter/aframe_exporter.py create mode 100644 aframe_exporter/icons/favicon.ico diff --git a/aframe_exporter/LICENSE b/aframe_exporter/LICENSE new file mode 100644 index 000000000..3d0f5908e --- /dev/null +++ b/aframe_exporter/LICENSE @@ -0,0 +1,23 @@ +MIT License + +Copyright (c) 2024 Banyapon Poolsawas associated with +College of Creative Design and Entertainment Technology, +Dhurakij Pundit University and Daydev Co., Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/aframe_exporter/README.md b/aframe_exporter/README.md new file mode 100644 index 000000000..f417eca2a --- /dev/null +++ b/aframe_exporter/README.md @@ -0,0 +1,52 @@ +# Blender A-Frame Exporter + +[![Blender Version](https://img.shields.io/badge/Blender-3.0+-orange.svg)](https://www.blender.org/) [![Blender Version](https://img.shields.io/badge/Blender-4.0+-orange.svg)](https://www.blender.org/) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + +This Blender add-on simplifies the process of exporting your 3D scenes into interactive web experiences using A-Frame, a popular web framework for building virtual reality (VR) and augmented reality (AR) experiences. + +## Features + +![Showcase](https://github.com/banyapon/Blender-Aframe-Exporter/blob/main/dist/8.png?raw=true) + +* **Seamless Export:** Quickly export your entire Blender scene, including models, materials, and animations, to A-Frame HTML and GLB (binary glTF) files. +* **Collision Detection:** Automatically add collision detection to your exported models using A-Frame's physics system, enabling interactive experiences. +* **Camera Controls:** Easily set up basic WASD controls for navigating your A-Frame scene with the camera. +* **Customization:** Customize the generated A-Frame code to add additional features, components, or interactions. + +## Installation + +1. Download the latest release of the add-on (`.zip` file) from the [Releases](https://github.com/banyapon/Blender-Aframe-Exporter/releases/tag/release) page. +2. In Blender, go to `Edit` > `Preferences` > `Add-ons` > `Install...` +![Go to `Edit` > `Preferences` > `Add-ons` > `Install](https://raw.githubusercontent.com/banyapon/Blender-Aframe-Exporter/main/dist/1.png) +3. Select the downloaded `.zip` file and click `Install Add-on`. +![Zip File](https://github.com/banyapon/Blender-Aframe-Exporter/blob/main/dist/2.png?raw=true) +4. Enable the "A-Frame Exporter" add-on in the list. +![Enable add-on](https://github.com/banyapon/Blender-Aframe-Exporter/blob/main/dist/3.png?raw=true) + +## Usage + +1. Create your 3D scene in Blender. +![Create Scene](https://github.com/banyapon/Blender-Aframe-Exporter/blob/main/dist/5.png?raw=true) +2. Go to `File` > `Export` > `A-Frame (.html)`. + + ![Export Aframe](https://github.com/banyapon/Blender-Aframe-Exporter/blob/main/dist/6.png?raw=true) + +3. Choose a location to save the files and click `Export A-Frame`. +![VS Code](https://github.com/banyapon/Blender-Aframe-Exporter/blob/main/dist/7.png?raw=true) +4. The add-on will generate an HTML file (`your_scene_name.html`) and a GLB file (`your_scene_name.glb`). +5. Open the HTML file in a web browser to view your interactive A-Frame scene. +![WebXR](https://github.com/banyapon/Blender-Aframe-Exporter/blob/main/dist/9.png?raw=true) + +## Additional Notes + +* Make sure you have a web server running to view the exported HTML file correctly. +* For more advanced A-Frame features and customization, refer to the [A-Frame documentation](https://aframe.io/docs/). + +## Contributing + +Contributions are welcome! Feel free to submit issues, feature requests, or pull requests. + +## License + +This add-on is released under the MIT License. diff --git a/aframe_exporter/__init__.py b/aframe_exporter/__init__.py new file mode 100644 index 000000000..d7c0f08d2 --- /dev/null +++ b/aframe_exporter/__init__.py @@ -0,0 +1,27 @@ +import bpy +from . import aframe_exporter + +bl_info = { + "name": "A-Frame Exporter", + "author": "Banyapon Poolsawas", + "version": (1, 0, 2), + "blender": (4, 0, 1), + "location": "File > Export", + "description": "Export Blender scene to A-Frame HTML and GLB for WebXR", + "warning": "", + "category": "Export", +} + +def menu_func_export(self, context): + self.layout.operator(aframe_exporter.ExportAFrame.bl_idname, text="A-Frame (.html)") + +def register(): + bpy.utils.register_class(aframe_exporter.ExportAFrame) + bpy.types.TOPBAR_MT_file_export.append(menu_func_export) + +def unregister(): + bpy.utils.unregister_class(aframe_exporter.ExportAFrame) + bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) + +if __name__ == "__main__": + register() \ No newline at end of file diff --git a/aframe_exporter/aframe_exporter.py b/aframe_exporter/aframe_exporter.py new file mode 100644 index 000000000..8e6f19ebc --- /dev/null +++ b/aframe_exporter/aframe_exporter.py @@ -0,0 +1,54 @@ +import bpy +import os +import shutil +from bpy_extras.io_utils import ExportHelper + +class ExportAFrame(bpy.types.Operator, ExportHelper): + bl_idname = "export_scene.aframe" + bl_label = "Export A-Frame" + filename_ext = ".html" + + def execute(self, context): + filepath = self.filepath + glb_filepath = os.path.splitext(filepath)[0] + ".glb" + + # Export GLB + bpy.ops.export_scene.gltf(filepath=glb_filepath, export_format='GLB') + + # Copy favicon.ico if it exists + favicon_path = os.path.join(os.path.dirname(__file__), "icons", "favicon.ico") + if os.path.exists(favicon_path): + shutil.copy(favicon_path, os.path.dirname(filepath)) + + # Create HTML (A-Frame) + with open(filepath, "w") as f: + f.write(f""" + + + + + + Aframe Exporter + + + + + + + + + + + + + + + + + + + + + """) + + return {'FINISHED'} diff --git a/aframe_exporter/icons/favicon.ico b/aframe_exporter/icons/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..1a2d02c47b276490488702e8068f3ab7ee4ba3ea GIT binary patch literal 15406 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