Coder Social home page Coder Social logo

lbartworks / openvgal Goto Github PK

View Code? Open in Web Editor NEW
13.0 3.0 5.0 71.65 MB

Virtual 3D gallery for art showcase. Based on Babylon.js

License: MIT License

HTML 43.70% JavaScript 27.82% Jupyter Notebook 9.73% Python 18.74%
babylonjs gallery html javascript python virtual-gallery virtual-reality webgl blender

openvgal's Introduction

LB.artworkds.Smaller.mp4

OpenVgal v0.5.1

(Open source Virtual Gallery) Virtual 3D gallery for art showcase. Based on Babylon.js

🆕 Update (22 December 2023). 🆕

Touch devices are now detected and better supported. Instruction on how to move around on the initial screen. Info field when hovering on the artwork. Im starting to do gallery designs. See below.

🆕 Update (22 August 2023). 🆕

consistency updates in the repository

🆕 Update (25 June 2023). 🆕

Great visual improvement aspect of automatic galleries. The materials for the walls and floor are now on a style.json file. Less parameters hardwired into the code. More general way to generate the doors, they are one additional item in the north wall. Light position is dynamically adapted to the dimensions of the hall. White frames for the artworks.

🆕 Update (12 May 2023). 🆕

An existing .glb template (hall) can now be populated with existing place-holders. This enables high-quality rendering and/or texture baking while the asset remain in the server and are loaded in real time.

🆕 Update (5 March 2023). 🆕

ON-the-fly built incorporated. If the .glb objects are not available the code will try to build the hall from scratch based on the images. Of course the images and materials need to be available in the web server.


Open Vgal started in June 2022 as a personal project to provide anyone a way to build a virtual gallery programmatically. What this means is that you do not need to design the hall or halls of the galleries, or deal with the 3D work, or the browser code to move around it if you do not want. You just need to describe the dimensions of the halls and the folders with the artwork images.

A demonstration of the gallery can be seen here: https://nostromophoto.com/virtual/virtual.html At the current stage you still need some effort/skills to create it. I hope it gets simplified in the following versions and with the help of the community. This is currently needed to use Vgal:

  • A web server to host the final virtual gallery/ies
  • (optional) A working installation of python to generate the .json file
  • A local webserver to generate the galleries and do the tests

🎨 If you want to create your own galleries you can go directly to the How to create your gallery section. Currently there is no video tutorial but I can create if there is demand for it.

💥 I have started creating gallery designs in Blender. You can see my Antarctica gallery, a template with ~100 placeholders. You can also purchase the Kraken gallery: https://oncyber.io/marketplace?buy=thekrakengallery

🛠️ If you want to contribute or further develop, the following sections explain some of the internal working of the code. You may look at the TODO list

Disclaimer: I am not an expert in javascript or Babylon.js. If you find parts of the code that can be written in a more academic way, feel free to help.

0. Structure of Open Vgal

The project is structured around three key elements:

  • A json file that describes the structure and content of the gallery halls.
  • A gallery builder that creates .glb files for each hall. Glb files is the binary version of GLTF, an open format to describe 3D scenes and models. Each hall will have its own file to avoid having a single very large file.
  • A gallery visualizer that creates the virtual experience using a web browser

Open Vgal uses a building.json file to describe the structure of galleries. The format is aimed to be flexible enough to accommodate a single hall or interconnecting halls in an arbitrary structure (not completely arbitrary at the moment). It always starts with a root gallery hall. That one can be a single gallery hall with artworks or you can have a gallery hall that connects with sub-galleries. Each hall can have items. Items are: either an artwork (a picture) or a door connecting to another gallery.

The building.json file follows a nested structure of dictionaries (dictionary is understood here as a data structure organized in the form of name/value pairs). The highest level structure (level 1) lists all the halls in the gallery.

Example of the level 1 structure:

{
“root”: root_dictionary,
“another_hall”: hall_dictionary,
…
“last_hall”: hallN_dictionary
}

The root_dictionary or the hallN_dictionary are level 2 dictionaries describing the characteristics of the hall. Each level 2 dictionary has two compulsory keys in the dictionary:

  • A geometry list (or array) that describes the geometry and dimensions of the hall, which will have a rectangular shape. The list contains the numberical values correspoing to [width, length, wall_height, #items north wall, #items south wall, #items west wall, #items east wall].
  • A parent field with the hall name that will give access to it. Note that the root hall has “none” as parent.

In addition to the two compulsory keys, it will have additional keys with the contents (items) of the hall.

Example of the level 1 and level 2 structure:

{
“root”:{
	“geometry”:[…],
	“parent”: “none”,
	“item1”:{…},
	“item2”: {…},
	“last item”: {…},
},
“another gallery”:{…},
“yet another gallery”: {…},
…
“last gallery”: {…}
}

Each of the items (item1, item2, etc...) consist of a level 3 dictionary with the following keys:

  • A resource key with the path to the file containing either the picture or the gallery (a .glb file)
  • A resource_type key that can have two values: [“door” | “image”]
  • width. For gallery type describes the dimension of the door. For images it will have values between 0 and 1.Depending on the aspect ratio, either the width or the height are expected to be equal to 1 and the other one lower than 1.
  • height. Same as previous.

Example of the level 1, 2 and 3 dictionaries:

{
“root”:{
	“geometry”:[…],
	“parent”: “none”,
	“item_name” : {
		“resource”: "another gallery.glb",
		“resource_type”: “door”,
		“width”:1,
		“height”: 2
	},
	“item2”: {
		“resource”: "galleryfolder/masterpiece.jpg",
		“resource_type”: “image”,
		“width”:1,
		“height”: "0.7"
	},
	“last item”: {…},
},
“another gallery”:{…},
“yet another gallery”: {…},
…
“last gallery”: {…}
}

At the bottom the file contains a technical section: "Technical": { "ambientLight": 1, "pointLight": 20, "scaleFactor": 3, "verticalPosition": 0.4 }

1. Json file creation

Although it is possible to get the building.json file created manually, as soon as several halls are interconnected with a few tens of items, this will not be practical. As an alternative a python jupyter notebook is provided to generate the .json file based on a more intuitive .csv file The csv file will get the following fields or columns:

  • Gallery name (name of the hall)
  • Parent (hall name of the parent. "none" for the root9
  • Folder (local filesystem folder with all the images of the hall)
  • Width (of the hall)
  • Length (of the hall)
  • Height (of the hall walls)
  • #items in the north wall
  • #items in the sounth wall
  • #items in the wwest wall
  • #items in the east wall

Notice that despite the notebook must know the complete local path of the images, it will only include the file name in the .json file.

2. Gallery builder

The gallery builder consists of html/javascript code that takes as an input the bulding.json file and creates binary (.glb) files. One file for each hall. It runs as a local web page (.html) and uses the rendering and export capabilities of Babylon.JS. From a programming point of view it would probably make more sense to create a node.js program. It is easier to install a lightweight web server than node.js, and that is the reason for the provisional choice.

Most of the job is done at the rb(config_file, room_name, scene) subroutine. It will create first the floor and walls of the hall. The information is obtained from the geometry contanined in building.json. Currently some parameters at the beginning of the subroutine are fixed:

	let door_height=3;		// dimensions of the door to the parent gallery
	let door_width=2;
	let item_separation=0.1; 	//this prevents that items and walls are co-planar		
	let item_size=2;		//parameter controlling the scale of the items

They control the size of the parent doors, as well as a general scale parameter for the items.

The materials for floor and walls are read from the styles.json. The textures are available in the repository (/materials folder). Then it will go through all the items in the hall (doors or artworks) and will create planes with one of these two materials:

  • a plain color + text for the doors
  • a texture with the images of the artwork

All the halls, except the root one, will have an additional item always: the door to get back to their parent hall.

Depending on the size of the halls and the number of them, there may be some issues with the file size or the memory usage. Halls of less than 50 images (1M pix resolution aprox) have worked well so far. Notice that with the addition of "on-the-fly" generation the role of the gallery builder is secondary. See next section.

3. Gallery viewer

The gallery viewer is an html page with javascript code to start the babylon engine and handle the following tasks:

  • Read the building.json file and create the root hall. For the root hall, or any other hall:
    • First it will try to to pull from the server a glb file with the name of the "resoure" field
    • If it does not exist, it will try to pull up a glb file with a template version ("T_" prefix) of the "resource" field
    • If none exist is will generate it on the fly
  • Creaate a kebyboard controller and camera to navigate the galleries in a first-person shooter style. You can rotate with the mouse and move in the four directions with the arrow keys.
  • Create an event listener for each door in a hall. When the visitor hovers on those doors the mouse icon changes. The user can teleport from one hall to another by clicking on the door
  • If the user chooses another hall, the code pulls up in the background the .glb file and show a progress bar screen.
  • Swap the scene contents but keep in memory the previous halls for faster interaction if the user returns to previously visited halls.

The glb files can be generated with the Gallery builder or any other software. In the latter case, you need to follow this convention:

  • If the glb file is a full gallery (no "T_" prefix), the mesh representing the door will have a name with the form "d_XXX", where XXX is the hall to which the door takes you (d_root for the main hall)
  • If the glb file is a template gallery, i.e. it only misses the textures of the artworks:
    • you must create a door mesh and name is as in the previous point
    • you must identify the planes where to put the textures by naming them YYYYYY_N, where "YYYYYY" will be the name of the resource (image name) and "N" a sequence number.

The gallery shown on the video or in my website has one main (root) hall created in Blender and with all textures baked. The other 6 galleries are generated on the fly. I also have a template GLB file created with Blender (not updated in this repo yet).

4. Steps to create a gallery

(This is a tutorial from v0.1, some aspects may need some review).

4.0 Preparatory work

  1. Organize each of the artwork images for each hall on a different folder. Put all the images (1 Mpix advised) of each hall in one folder. If you do not want to use your own files, I provide a zip file with examples.
  2. Create a spreadsheet (see example) with the .csv fields and save it. You can follow along with that csv file and the example halls.
  3. Install a local webserver. A simple and light option available in different operative systems is Devd. If you do not want to compile it you can download a portable version here. Once you download it, uncompress it and place it in some folder you fancy. You can run it from the command line with the command "devd -ol ." (the double quotes are not needed). To access the server simply type in your browser http://localhost.
  4. If you do not have a working python installation with jupyter notebooks, install it. You can go to the Anaconda website
  5. Download or clone the vgal repository. For consistency, put it inside the local webserver folder. The local webserver would look like:

  1. If you want to use the example galleries, download this zip file. Uncompress the zip archive in the vgal/python folder. You will notice that 4 folders (gallery1, gallery2, gallery3 and gallery4) will be created. This example has, hence, 4 halls. If you want to create your own halls you will need to replace these folder with you own folders.

Json file creation

  1. Run the jupyter notebook and load the notebook VR_gallery.ipynb, which should be in the vgal/python folder. This notebook will create the buliding.json file. If you follow these instructions you do not need to change the paths. In case the building.jsonfile or the gallery folders are in different locations you can customize the first variables of the notebook (see below). Run the notebook nd everythig goes well a fresh buliding.json will be created at the web server root folder.
	csv_file='building.csv'
	output_file="../../building.json"
	image_types=('jpg', 'jpeg', 'png', 'tif')
	csv_separator=';'

In the following steps there are three possible options: to create a fully configured glb file (hall and artwork) with Babylon, to create a glb file (just the hall plus placeholders for the artwork) with some 3D tool, or do not create any glb file and render everything on the fly. The following 3 subsections discuss the 3 options

4.1 Hall builder (create a full glb file with babylon) [This part is discontinued and no longer supported. To be removed in the next version]

  1. If you do not have a web browser open already, do it and type in http://locahost. Navigate to the hall builder (if you follow along this installation it would be /vgal/hall_builder/room_processor.html. Upon loading, if all goes well, the page will inform that 5 halls are created (the root hall and the 4 gallery halls). Their corresponding files will be downloaded. The first javascript section of the html file has some variable to customize the location of the input / output files (see below)
	const config_filename='/building.json';
	const hallspics_prefix= '/vgal/python';
	const materials_folder='/vgal/materials';
  1. If it does not work you can have a look at the console to figure out what went wrong
  2. The downloaded files will be placed by the browser in the download default folder of your computer. You will need to manually move the 5 .glb files to the local webserver folder. Note that if you run the download several times, the filenames may no longer be the intended ones (for example root(1).glb instead of root.glb). Those names will not be recognized later, so either rename them or flush the download folder and run it again.
	const asset_location="/";
	const config_file_name="/building.json";
  1. Optionally you can check with the babylon sandbox that the halls show up as expected.

4.2 Hall template (create a glb hall with placeholders with some 3D tool)

The previous option comes with some drawbacks like the large size of the glb files and the limitations of Babylon to create scenes compared to other 3D modelling tools like Blender. As an alternative:

  • You can use blender to design a higher quality hall. That can include baked textures for a more efficient way to include complex lighting.
  • You can include placeholders for the artwork. The gallery viewer will retrieve the images and render them in the placeholders

In order to work in the way, this is necessary:

  • The resource glb file will need to have the T_ prefix. If the gallery viewer detects a hall resource with such prefix it will not include any element or material except the textures of the placeholders
  • The placeholders will need to be named using the same criterion of option 4.2 (ImageName + "_" + number)

The gallery Antarctica (https://nostromophoto.com/virtual/gallery_viewer/virtual_gallery.html) has been generated in this way. You can also check the blender file with python code to create the hall and placeholders. Notice that you would need to manually bake the textures. This options is only advised for seasoned Blender users.

4.3 On the fly creation (no glb file)

The third and easiest option is to simply skip steps 4.1 and 4.2 and DO NOT create a glb file. The gallery_viewer will create the hall on the fly completely using the information from the json file.

The galleries "Pakistan" and "PeruBolivia" are created in this way. Notice that the images (your artwork) will need to be uploaded into the server. You will need to configure the header parameters in the gallery_viewer.html file.

4.4 Visualize the gallery

  1. Open another web browser tab and go to http://localhost/vgal/gallery_viewer/virtual_gallery.html.
  2. Again the first javascript lines contain code with path options in case that the buliding.json or the .glb files are placed in a different location.
  3. If all goes well you should be able to navigate the virtual root hall and jump into the additional halls

4.5 Upload it to the internet

  1. Finally if you want anyone to see the contents, you will need to make them available into your own managed server or via a hosting service. Notice that the large files may be rejected by some suppliers (I found some have 10 MB size limits for each file).

FAQ

  • Can the font of the Halls name support extended codesets? The current 3D font that OpenVgal uses does not support extended characters. It will be included in the styles of a future version
  • Can the items be larger? Currently the width/height comes as a relative factor on a global size hardcoded in javascript (details)
  • Could lights/shadows be incorporated? The best way to do that would be generating the halls with blender and bake (precalculate) the textures. I have some experiments baking lightmaps, you can check them in this youtube video

TODO

  • On the fly rendering of the hall and items (pure babylon.js)
  • Hybrid mode where you load a glb with the hall but the items are loaded in real time
  • A blender based hall builder with textures baked manually.
  • A blender based hall builder with baked textures automated.
  • GUI to interactively get all the inputs and get visual feedback of the appearance.
  • Customization of materials via input files
  • Alternative hall templates, not simply a rectangular hall.
  • Better management of mobile devices
  • Framing for artwork
  • Titles and information for the artwork
  • Support for VR devices
  • Code to detect overlapping artwork or erroneous configurations
  • Baking lightmaps
  • Include the 3D font as part of the style json file

openvgal's People

Contributors

lbartworks avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

openvgal's Issues

styles.json is missing

I followed the instruction but I couldn't find styles.json.
If possible, please add the styles.json file as a sample.
Thanks

Some code correction requirements

Greetings!

First of all thank you very much for this awesome software to be available as Open Source product.
I searched the Internet for something like this to show photos in a gallery-style way.

Now let me write my experience in an issue report:
For this product test I use Windows 10 + Firefox + Apache webserver for win64 - and followed the instruction ("4. Steps to create a gallery") as of 20. Jan. 2024.

#####################################

4.0 Main step: Preparation

  1. Organizing photos in various gallery* subdirectories, keeping in mind the <50 images / dir rules of thumb mentioned later in the instructions - Check.

#-----------------#

  1. create a csv file (building.csv) in the python subdirectory -- Check.

#-----------------#

  1. Install local webserver (apache) - Check.

#-----------------#

  1. Install jupyter notebooks --- and on windows painfully learn how to set it to use the same root dir as the Apache. - Check.

#-----------------#

  1. Download the VGAL repo. - Check,

#-----------------#

  1. (actually the 6. step is marked as 7. in the instructions) Galleries are already there. - Check.

#-----------------#

  1. Run the jupyter notebook and load the notebook VR_gallery.ipynb...
    Well: there are some concerns here.

The default values in the VR_gallery.ipynb for:
"building["Technical"]["ambientLight"]=10\n",
"building["Technical"]["pointLight"]=50\n",

Are too much. ambientLight could be 1 while pointlight should be 20.

Also if the image files inside the gallery directories have the extension with capital letters for example .JPG the script simply gets stuck and Jupyter Notebook does not say at which file.
It is good to have the "Handle.exe" tool for windows (something like the "fuser" on Linux ) to find the file where the script stands at, having the PID holding the file - as well as cygwin for bash-like shell commands and iterations for faster file operation thoughout the gallery directories.

Another point here is the aspect ratio of images (height / width): the script seems like tries to guess (?!) the ascect ratio however in some cases they have to be corrected manually in the building.json file - which is a pain in the A job when there are hundreds of images and dozens of galleries.

Of course in case of "dozens of galleries" with <50 images each - the room sizing must be set manually as a trial and error method until the right measure has been found. (the gallery viewer is a good way to test it later on).

Hint for users:
Also the source csv file (building.csv) should be plain, therefore it is not good to edit them - for example - in Excel so there should be no apostrophes present.
The building.json file will be in the root dir of the apache (by default: [Drive]:\Apache24\htdocs directory). It is advised to keep it there and to copy the styles.json there as well. Also copy the new building.json into the vgal subdirectory.

#-----------------#

4.1 Main step: Hall Builder.

  1. In "/vgal/hall_builder/room_processor.html" I guess the styles.json is missing from the constants.
    It calls the "./room_builder_aux.js" java script right at the beginning.

In Firefox the room_builder_aux.js script run on an error stating that "floor_material" is not defined.
It is defined, and the script seems good:
floor_material = materials[data.chosenStyles.chosenFloorStyle];

(Also to mention that the "vgal/blender/scrypt.py" overrides the material attributes.)

When I manually declare the variable to match the information contained in styles.json file as
floor_material = "Wooden";
The next error is that the rb function is not defined in room_processor.html.
As I am not too familiar with the concept (beginner level in python and in Java) so I leave this as it is.

Hall Builder failed for me (this is step 10.) on Windows 10 + Firefox (tried it in Edge and IE compatibility mode as well - No use).

#-----------------#

  1. There is no step 9.

#-----------------#

  1. Yep, Hall Builder failed.

#-----------------#

  1. No downladed room files due to error.

#-----------------#

  1. There is no step 12.

#-----------------#

  1. Probably cannot do without generated files.

#-----------------#

4.2 Main Step: Hall template --- I skipped this during my tests.

#-----------------#

4.3 Main step: On the fly creation (no glb file)
"http://localhost/vgal/gallery_viewer/virtual_gallery.html"

The first problem is with the double quites - they shall be single apostrophes:
const asset_location="/";
const config_file_name="/building.json";
const styles_file_name="/styles.json"
const materials_folder='/vgal/materials';
const hallspics_prefix= '/vgal';

About
const hallspics_prefix= '/vgal';
should this point to /vgal/python ?

Otherwise it works like charm if the styles.json is also in the root directory of the webserver.

The only issue is that the internal room doors are not working as a link back to the main hall (root) so if I want to get back into the corridor I have to refresh the page.

Plus another big issue after the GalleryViewer works: when I want to export the room(s) to GLB file(s) inside the "GalleryViewer" (babylon.js) the webpage informs me about the Export being in progress... and nothing happens.
There the Firefox web console gives the following information:

BJS - [timestamp]: GLTF2Export is not available. Make sure to load the serializers library

Uncaught TypeError: jl.GLTF2Export is undefined
exportGLTF toolsTabComponent.tsx:286
onClick toolsTabComponent.tsx:501
onClick buttonLineComponent.tsx:20
React 11
unstable_runWithPriority scheduler.production.min.js:18
React 3

The coding reference of Firefox shows the following:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Unexpected_type?utm_source=mozilla&utm_medium=firefox-console-errors&utm_campaign=default

#-----------------#

So overall the project is very exciting and satisfying as it works like charm in GalleryViewer and needs some manual preparation to make it totally custom.
The textures and sizes etc. are also manually customizable and is a good feature.

Definitely worth to continue developing it, keep up the good work!

Sincerely,
Flow-R-Ian

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.