The Gallery - An Interactive 3D Art Gallery

My first Three.js and react-three-fiber project. A 3D virtual gallery to showcase some of my drawings and paintings… let me know what you think / if you find any issues…

I’m also keen to get it working on mobile so any advice on touch controls would be greatly appreciated

11 Likes

Damn, that’s hot.

4 Likes

This is beautiful, especially the mood and lighting. I am currently working on mobile/touch support, and will let you know if I figure it out! Curious how you got collision detection working, that was a major sticking point for me. Let me know, when you have some time to explain! I looked at your code but didn’t see where that idea was implemented. Thanks :smiley:

1 Like

Hey, thanks for the kind words. Glad you like my project. Would be cool to see what you come up with for touch/mobile support.

In regards to the collision detection, check out
use-cannon

Implementation is all documented in the readme so you should find it easy to get it working if you give that a read :+1:t4:

1 Like

hello there, excellent job. I have my own gallery too and I was trying to migrate it to react and your repository would be very helpful. But when I run the localhost (after npm i and all) there are many errors in the browser console, what is happening? I understand that the one that is online works through gh pages from the same repository and it works correctly. regards!

Hi deanssmart, please require your tremendous help to know how to add cannon es blocking for .glb models which have complex child meshes, object 3D and groups. I’m stuck up in the middle of my program and unable to figure out the solution. Im writing in Three JS…

Example code I tried as:
const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath(‘./js/draco/’);
loader.setDRACOLoader(dracoLoader);
loader.load(“asset/landing_room_bake.glb”, (gltf) => {
gltf.scene.scale.set(0.01,0.01,0.01)
scene.add(gltf.scene);

  // Set up Cannon.js physics for each mesh
  gltf.scene.traverse((child) => {
        if (child.isMesh) {
              (child.geometry.vertices == undefined) ? child.geometry.vertices = [] : true;
              const shape = new CANNON.ConvexPolyhedron(
                    child.geometry.vertices.map(
                          (v) => new CANNON.Vec3(v.x, v.y, v.z)
                    )
              );
              const body = new CANNON.Body({ mass: 0 });
              body.addShape(shape);
              body.position.copy(child.position);
              body.quaternion.copy(child.quaternion);
              world.addBody(body);
              child.userData.physicsBody = body;
        }
        else if(child.type == "Object3D")
        {
            let myGeometry = new THREE.Mesh(gltf.scene.geometry, child);
            (myGeometry.geometry.vertices == undefined) ? myGeometry.geometry.vertices = [] : true;
              const shape = new CANNON.ConvexPolyhedron(
                myGeometry.geometry.vertices.map(
                          (v) => new CANNON.Vec3(v.x, v.y, v.z)
                    )
              );
              const body = new CANNON.Body({ mass: 0 });
              body.addShape(shape);
              body.position.copy(child.position);
              body.quaternion.copy(child.quaternion);
              world.addBody(body);
              child.userData.physicsBody = body;
        }
        else if(child.type == "Group")
        {
            for(let i=0; i< child.children.length; i++)
            {
                if(child.type == "Mesh")
                {
                    (child.children[i].geometry.vertices == undefined) ? child.children[i].geometry.vertices = [] : true;
                    const shape = new CANNON.ConvexPolyhedron(
                            child.children[i].geometry.vertices.map(
                                (v) => new CANNON.Vec3(v.x, v.y, v.z)
                            )
                    );
                    const body = new CANNON.Body({ mass: 0 });
                    body.addShape(shape);
                    body.position.copy(child.children[i].position);
                    body.quaternion.copy(child.children[i].quaternion);
                    world.addBody(body);
                    child.children[i].userData.physicsBody = body;
                }
            }
        }
  });

});

const world = new CANNON.World();
world.gravity.set(0, -9.82, 0);
world.broadphase = new CANNON.SAPBroadphase(world);
world.solver = new CANNON.GSSolver();
//world.defaultContactMaterial.friction = 0.1;
//world.defaultContactMaterial.restitution = 0.3;

const groundShape = new CANNON.Plane();
const groundBody = new CANNON.Body({ mass: 0 });
groundBody.addShape(groundShape);
world.addBody(groundBody);

hahahahah very close details

Do you have a solution?? please help