0

If I add a tetrahedron to a three.js scene like this, how can I correct the tilt of it so that it's bottom face is flat, reset the y axis so I can rotate around it correctly?

//dummy object
var dummy = new THREE.Mesh( new THREE.CubeGeometry( 1, 500, 1 ), new THREE.MeshBasicMaterial() );
dummy.position.x = 0;
dummy.position.z = 0;
scene.add( dummy );

// tetrahedron
var points = [
new THREE.Vector3( 200, 0, 0 ), //bottom right
new THREE.Vector3( 0, 200, 0 ), //top
new THREE.Vector3( 0, 0, 200 ), //bottom left
new THREE.Vector3( 200, 200, 200 ) //bottom back    
];

object = THREE.SceneUtils.createMultiMaterialObject( new THREE.ConvexGeometry( points ), materials );

object.position.set( -110, 0, -110 );
object.rotation.set( 0.7, 0.0, -0.7 );

dummy.add( object );
garrettlynchirl
  • 790
  • 8
  • 23
  • Any reason you're not using THREE.TetrahedronGeometry? Ideally it would be best to just fix your initial geometry, instead of rotating it after-the-fact. – Brendan Annable Jan 21 '16 at 03:04
  • What @BrendanAnnable said. Building it properly is best. But it that isn't an available option, then use `object.geometry.computeFaceNormals()` to get the appropriate directions, and then get a transform based the bottom face's normal. I leave it to you to find that normal vector, called, say, `v` -- then make a new `Matrix4` and apply `.lookAt()` from the origin to `v`, and then `.getInverse()` which will give you the rotation you can apply to make the tetrahedron point "up" -- it will be slightly off-center, but you only asked about tilt. – bjorke Jan 21 '16 at 17:43
  • From what I understand (just started using three js) THREE.TetrahedronGeometry builds a tetrahedron automatically using a radius. I need to know the positions of all the points of the tetrahedron so its preferable to use a list of vectors. I have managed to tilt the tetrahedron now by using a dummy object (see code in edited question) and corrected my tetrahedron to be a regular tetrahedron but I don't know how much I need to `object.position.set( -110, 0, -110 )` and `object.rotation.set( 0.7, 0.0, -0.7 )` to get the tetrahedron correctly positioned at 0, 0, 0 with a point facing upward. – garrettlynchirl Jan 22 '16 at 13:50
  • Maybe http://stackoverflow.com/a/12786160/1461008 will help you. – WestLangley Jan 22 '16 at 20:04

1 Answers1

0

@WestLangley, yes I found that post a few hours before you replied and got it to work (copied below). Don't fully understand the math in makeRotationAxis() or why the offset of -115 on the x and z axis, tetrahedron.position.set( -115, 0, -115 ), is correct for a tetrahedron that has 200 for it's vectors. It was trial and error, would feel more comfortable is I understood what calculation to do so I can change sizes.

<!-- language: lang-js -->
<!DOCTYPE html>
<html lang="en">
<head>
    <title>three.js webgl - convex geometry</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body {
            font-family: Monospace;
            background-color: #000;
            margin: 0px;
            overflow: hidden;
        }

        canvas { width: 500px; height: 500px }
    </style>
</head>
<body>

    <script src="three.min.js"></script>
    <script src="js/geometries/ConvexGeometry.js"></script>
    <script src="js/Detector.js"></script>

    <script>

        if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

        var container;
        var camera, scene, renderer;

        init();
        animate();

        function init() {

            container = document.createElement( 'div' );
            document.body.appendChild( container );

            camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
            camera.position.y = 400;

            scene = new THREE.Scene();

            var light, object, materials;

            scene.add( new THREE.AmbientLight( 0x404040 ) );

            light = new THREE.DirectionalLight( 0xffffff );
            light.position.set( 0, 1, 0 );
            scene.add( light );

            materials = [
                new THREE.MeshLambertMaterial( { color: 0xffffff, wireframe: false, transparent: false, opacity: 0.5, wireframeLinewidth: 2, wireframeLinejoin: "miter" } )
            ];

            //dummy line object
            var dummy = new THREE.Mesh( new THREE.CubeGeometry( 1, 500, 1 ), new THREE.MeshLambertMaterial() );
            dummy.position.x = 0;
            dummy.position.z = 0;
            scene.add( dummy );

            //tetrahedron points
            var points = [
                new THREE.Vector3( 0, 0, 200 ), //bottom right
                new THREE.Vector3( 0, 200, 0 ), //top
                new THREE.Vector3( 200, 0, 0 ), //bottom left
                new THREE.Vector3( 200, 200, 200 ) //bottom back

            ];          

            tetrahedron = THREE.SceneUtils.createMultiMaterialObject( new THREE.ConvexGeometry( points ), materials );

            //fix the rotation so that the point of the tetrahedron points up
            tetrahedron.applyMatrix( new THREE.Matrix4().makeRotationAxis( new THREE.Vector3( 1, 0, -1 ).normalize(), Math.atan( Math.sqrt(2)) ) );

            //fix the offset
            tetrahedron.position.set( -115, 0, -115 );

            //add the tetrahedron to the dummy line object
            dummy.add( tetrahedron );

            renderer = new THREE.WebGLRenderer( { antialias: true } );
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );
            container.appendChild( renderer.domElement );

            window.addEventListener( 'resize', onWindowResize, false );

        }

        function onWindowResize() {

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            renderer.setSize( window.innerWidth, window.innerHeight );

        }

        function animate() {

            requestAnimationFrame( animate );

            render();
            stats.update();

        }

        function render() {

            var timer = Date.now() * 0.0001;

            camera.position.x = 800;
            camera.position.y = 500;
            camera.position.z = 800;

            camera.lookAt( scene.position );

            for ( var i = 0, l = scene.children.length; i < l; i ++ ) {

                var object = scene.children[ i ];
                object.rotation.y = timer * 2.5;

            }

            renderer.render( scene, camera );

        }

    </script>

</body>

garrettlynchirl
  • 790
  • 8
  • 23