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;

/*
*
* 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.position.set(0, 0, 100);

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

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

/*
*
*
*/

// 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);

// 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.position.z = -1;

/*
* 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) {

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
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) {
velocityX *= -1;
ball.position.x = (ball.position.x < 0) ? borders * -1 : borders;
}

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

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

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

requestAnimationFrame(render);
}

render();

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