THREE.js - moving a 3D ball with a rotation

by Roey Zada   Last Updated September 02, 2018 02:13 AM

I'm new to THREE.js and with a very poor knowledge in physics - but I am trying to build a football game engine (viewed from top) and right now I'm struggling with the movement of the ball.

when trying to move the ball from side to side, the rotation is always facing one direction and I dont understand how to make this rotate in the direction its moving at.

Ive added a simple code showing this issue. your help is much appreciated.

/*
        *
        * SET UP MOTION PARAMS
        * 
        */

        var degrees = 10;
        var power = 1;
        var angleRad = degrees * Math.PI / 120;

        var velocityX = Math.cos(angleRad) * power;
        var velocityY = Math.sin(angleRad) * power;
        var velocityZ = 1;

        var friction = 1;
        var gravity = 0.2;
        var bounciness = 0.9;



        window.onload = function (params) {

            /*
            *
            * SET UP THE WORLD
            * 
            */
            
            
            
            //set up the ratio
            var gWidth = window.innerWidth;
            var gHeight = window.innerHeight;
            var ratio = gWidth / gHeight;
            var borders = [40, 24] //indicate where the ball needs to move in mirror position


            //set the scene
            scene = new THREE.Scene();
            scene.background = new THREE.Color(0xeaeaea);

            //set the camera
            var camera = new THREE.PerspectiveCamera(35, ratio, 0.1, 1000);
            camera.position.z = 120;   

            //set the light
            var light = new THREE.SpotLight(0xffffff, 1);
            light.position.set(100, 1, 0); 		
            light.castShadow = true;         
            light.position.set(0, 0, 100);
            scene.add(light);

            //  set the renderer 
            var renderer = new THREE.WebGLRenderer();

            //properties for casting shadow
            renderer.shadowMap.enabled = true;
            renderer.shadowMap.type = THREE.PCFSoftShadowMap; 

            renderer.setSize(gWidth, gHeight);
            document.body.appendChild(renderer.domElement);



            
            /*
            *
            * ADD MESH TO SCENE
            * 
            */


            // create and add the ball
            var geometry = new THREE.SphereGeometry(5, 5, 5);
            var material = new THREE.MeshLambertMaterial({ color: 'gray' });
            var ball = new THREE.Mesh(geometry, material);

            ball.castShadow = true;
            ball.receiveShadow = false;
            scene.add(ball);


            
            // create and add the field
            var margin = 20;
            var fieldRatio = 105 / 68;

            var width = 90;
            var height = width / fieldRatio;

            var material = new THREE.MeshLambertMaterial({ color: 'green' });
            var geometry = new THREE.BoxGeometry(width, height, 1);
            var field = new THREE.Mesh(geometry, material);

            field.receiveShadow = true;
            field.position.z = -1;
            scene.add(field);




            /*
            * setting up rotation axis 
            */


            var rotation_matrix = null;

            var setQuaternions = function () {
                setMatrix();
                ball.rotation.set(Math.PI / 2, Math.PI / 4, Math.PI / 4); // Set initial rotation
                ball.matrix.makeRotationFromEuler(ball.rotation); // Apply rotation to the object's matrix
            }

            var setMatrix = function () {
                rotation_matrix = new THREE.Matrix4().makeRotationZ(angleRad); // Animated rotation will be in .01 radians along object's X axis
            }

            setQuaternions();


            /*
            *
            * ANIMATION STEP
            * 
            */

            var render = function (params) {

                // add velocity to ball
                ball.position.x += velocityX;
                ball.position.z += velocityZ;
                ball.position.y += velocityY;


                //validate if ball is stop moving
                if (Math.abs(velocityX) < 0.02 && Math.abs(velocityY) < 0.02) {
                    console.log("DONE!");
                    return;
                }



                // handle boucing effect
                if (ball.position.z < 1) {
                    velocityZ *= -bounciness;
                    ball.position.z = 1
                }


                // Update the object's rotation & apply it
                ball.matrix.multiply(rotation_matrix);
                ball.rotation.setFromRotationMatrix(ball.matrix);


                //reducing speed by friction
                angleRad *= friction;
                velocityX *= friction;
                velocityY *= friction;
                velocityZ *= friction;


                //set up the matrix 
                setMatrix();
                


                //validate ball is withing its borders otherwise go in the mirror direction
                if (Math.abs(ball.position.x) > borders[0]) {
                    velocityX *= -1;
                    ball.position.x = (ball.position.x < 0) ? borders[0] * -1 : borders[0];
                }

                if (Math.abs(ball.position.y) > borders[1]) {
                    velocityY *= -1;
                    ball.position.y = (ball.position.y < 0) ? borders[1] * -1 : borders[1];
                }


                // reduce ball height with gravity
                velocityZ -= gravity;

                

                //render the page
                renderer.render(scene, camera);

                requestAnimationFrame(render);
            }

            render();

        }
body {
            padding: 0;
            margin: 0;
        }
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>
<html>

<head>

</head>

<body>
</body>

</html>



Related Questions



Implement Fast Inverse Square Root in Javascript?

Updated June 09, 2016 08:05 AM

custom SetInterval function in javascript

Updated September 05, 2016 09:05 AM