Utilize CannonJS to create a realistic floor where a ball can adhere to the surface

Newbie Inquiry: I'm attempting to drop a ball and have it stick to the floor or even roll over a plane. Currently, it's passing through the plane without any interaction. I'm unsure of where I may have gone wrong or if there's an error in my approach.

var world, timeStep=1/60, scene, renderer, camera,
      icosahedronBody, sphereShape, groundShape,
      ground, groundBody, groundShape;
  // CONSTANTS
  var GRID_HELPER_SIZE = 40,
      GRID_HELPER_STEP = 2,
      MASS             = 5;

  initThree();
  initCannon();
  animate();

  function initCannon() {
    world                   = new CANNON.World();
    world.broadphase        = new CANNON.NaiveBroadphase();
    sphereShape             = new CANNON.Sphere();
    groundShape             = new CANNON.Plane();

    icosahedronBody         = new CANNON.Body({
                                    mass: MASS,
                                  });
    groundBody              = new CANNON.Body({
                                    mass: 0, // mass == 0 makes the body static
                                  });

    world.solver.iterations = 10;
    world.gravity.set(0,-9.8,0);
    world.defaultContactMaterial.contactEquationStiffness = 1e9;
    world.defaultContactMaterial.contactEquationRegularizationTime = 4;

    icosahedronBody.addShape(sphereShape);
    icosahedronBody.position.set(0,50,0)
    icosahedronBody.linearDamping     = 0.5;
    world.addBody(icosahedronBody);

    groundBody.addShape(groundShape);
    groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(0,1,0),-Math.PI/2);
    world.addBody(groundBody);

    var ballContact         = new CANNON.ContactMaterial( groundBody, icosahedronBody, 0.0, 0.0);

    world.addContactMaterial(ballContact);
  }

  function initThree(){
    // INITIALIZE CANVAS
    scene                 = new THREE.Scene();
    renderer              = new THREE.WebGLRenderer();
    camera                = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
    var light             = new THREE.AmbientLight( 0x404040 ),
        directionalLight  = new THREE.DirectionalLight( 0xffffff ),
        gridHelper        = new THREE.GridHelper( GRID_HELPER_SIZE, GRID_HELPER_STEP );

    renderer.setSize( window.innerWidth - 100 , window.innerHeight - 100 );
    renderer.setClearColor( 0x757575 );
    document.body.appendChild( renderer.domElement );
    camera.position.set(1,25,100); // camera position to x , y , z
    camera.lookAt( new THREE.Vector3() )
    directionalLight.position.set( 1, 0.75, 0.5 ).normalize();

    // INITIAL CANVAS
    scene.add( directionalLight );  
    scene.add( light );
    scene.add( camera );
    scene.add( gridHelper );

    // MATERIALS
    var icoGeometry = new THREE.IcosahedronGeometry(10, 1),
        icoMaterial = new THREE.MeshLambertMaterial( {color: 0xff0000} );
    icosahedron     = new THREE.Mesh( icoGeometry, icoMaterial );

    var groundGeometry = new THREE.BoxGeometry(100 , 1, 100),
        groundMaterial = new THREE.MeshLambertMaterial( {color: 0xcccccc} );
    ground             = new THREE.Mesh( groundGeometry, groundMaterial );
    ground.receiveShadow = true;

    // ADD OBJECTS TO SCENE
    scene.add( icosahedron );
    scene.add( ground );
  }    

  function animate() {
      requestAnimationFrame( animate );
      updatePhysics();
      render();
  }
  function updatePhysics() {
      // Step the physics world
      world.step(timeStep);
      // Copy coordinates from Cannon.js to Three.js
      icosahedron.position.copy(icosahedronBody.position);
      icosahedron.quaternion.copy(icosahedronBody.quaternion);

      ground.position.copy(groundBody.position);
      ground.quaternion.copy(groundBody.quaternion);
  }
  function render() {
      renderer.render( scene, camera );
  }

Answer №1

Your CANNON.Plane orientation seems to be incorrect. By default, its normal points in the Z direction, so rotating it -90 degrees along the positive X axis will align its normal with the positive Y direction (refer to the right hand rule):

groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1,0,0),-Math.PI/2);

Additionally, ensure that the BoxGeometry matches by making it thinner along its Z axis:

var groundGeometry = new THREE.BoxGeometry(100, 100, 1),

Note that the radius of the THREE.IcosahedronGeometry is 10, while the radius of the CANNON.Sphere is 1 (the default). Adjust the sphere's radius to 10 to match the three.js geometry:

sphereShape             = new CANNON.Sphere(10);

Make these changes and your simulation should function as intended. Best of luck!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Implement a JavaScript and jQuery code that alternates between fading in and fading out every two items in a

Can someone help me figure out how to create a loop that fades in and out every 2 items from an unordered list using jQuery? I've been trying to do this, but my loop only processes one item at a time. <div> <ul> <li>item1</li ...

Transferring sizable JavaScript array to the Web API

I've been grappling with this problem for two days... In my JavaScript code, I have a large array comprising 20,000 rows and 41 columns. This data was initially fetched in JavaScript via an ajax call, as shown below: var dataArray = []; var dataRequ ...

What is the method for obtaining the viewModel in a Knockout component?

I need to prepopulate a knockout component when the document is ready. This is the code I have written: function Finding(id, trigger) { var self = this; self.id = ko.observable(id); self.trigger = ko.observable(trigger); } function FindingVi ...

Seeking a method to attach information from a div to a hyperlink

As a complete novice in the world of CSS websites, I find myself struggling to accomplish what seems like a simple task. I am working with an automatically generated CSS/JavaScript website where on the "individual" page, a person's name is listed with ...

What methods can be used to replicate a network delay while conducting unit tests for an AngularJS controller?

I am currently utilizing the $httpBackend service within the ngMock module to emulate a GET request. The following is a sample controller code snippet sourced from the AngularJS documentation: // Example controller code function MyController($scope, $http ...

Each time `fs.writeFile` is invoked, it initiates a fresh line

Every time this code is run, I want it to create a new line of data instead of overwriting the previous one. For example, if it's executed once, it would display: Checked Status: ONLINE. However, upon subsequent runs, it should add another line direc ...

Invalid file name detected during the download process

Below is the Javascript code I currently use to download a pdf: var link = document.createElement('a'); link.innerHTML = 'Download PDF file'; link.download = "Report.pdf"; link.href = 'data:application/octet-stream;base64 ...

Tips for JavaScript validation before submitting a form in Zend framework

I created this JavaScript code for form validation, but it is also submitting data to the database even when the validation fails. I need help in modifying the code so that it only submits the data if the conditions are met. Below is the HTML code: <f ...

Conditions in Controller Made Easy with AngularJS

I have recently started working on implementing a notifications feature. The service will involve making a GET request to a specific URL which will then return an array of notifications. Within the controller, I am in the process of setting up a variable ...

What is the best way to access the second array in a JSON object?

I have successfully implemented autocomplete with JSON and PHP. It is working fine, but now I am facing a challenge in retrieving the second array from the JSON data. Below is the script I have used in source.php: <?php $req = "SELECT namaBarang, har ...

Setting up popover functionality in TypeScript with Bootstrap 4

Seeking assistance with initializing popovers using TypeScript. I am attempting to initialize each element with the data-toggle="popover" attribute found on the page using querySelectorAll(). Here is an example of what I have tried so far: export class P ...

html interactive/expandable tree

I've come across this code which generates an HTML tree, but I'm facing an issue where the tree expands every time I refresh the page. What I want to achieve is to have certain branches expanded and others collapsed when the page is opened, depe ...

In mongoose and nodejs, there is no method called .find()

I am encountering an issue while attempting to locate by id and receiving the error bankApp.find is not a function. Below is my schema: import {model, Schema} from "mongoose"; const StatusResponse = new Schema({ uniqueKey: {type: String, trim: true, ...

Tips for retaining the value of a variable when the page is reloaded

I need to store the value of the variable loggedIn, as it determines the behavior of a function in appComponent.html. Can you explain how I can achieve this? Template of app component: <li class="nav-item"> <a class ...

Transitioning a NPM project to the Apache server

Recently, I successfully managed to run a simple example project by following these steps: I downloaded and installed Node.js for windows x64. I then used Git to clone the project from https://github.com/BretCameron/three-js-sample.git Next, I ran t ...

Using a texture the same size as the original image in three.js / react-three-fiber: A step-by-step guide

I am facing a challenge in a project where I need to create a box to improve processing efficiency. The desired texture size is 16 px by 16 px. However, when I apply the texture to the box, it appears blurry regardless of the box size, as shown in the imag ...

Using the angular2-cookie library in an Angular 2 project built on the rc5 version

Starting a new angular2 rc5 project, I wanted to import the angular2 cookie module. After installing the module with npm, I made changes to my angular-cli-build.js file : npm install angular2-cookie edited my angular-cli-build.js file : module.exports ...

Encountering an Uncaught TypeError in Reactjs: The property 'groupsData' of null is not readable

While working on a ReactJs component, I encountered an issue with two basic ajax calls to different APIs. Even though I am sure that the URLs are functioning and returning data, I keep getting the following error message: Uncaught TypeError: Cannot read p ...

What is the Vue.js alternative to using appendChild for dynamically inserting new elements or components?

When working with Vue.js, I have successfully created a var app = new Vue({...}); and defined a component Vue.component('mycomponent', .... I am able to use this component by directly adding <mycomponent></mycomponent> in my HTML. How ...

Utilize String to Set Cookies

My goal is to utilize requestjs for making requests and sharing cookies across various JavaScript files and servers. To achieve this, I have chosen to store the cookies in a database as a string and retrieve them when necessary. The string format aligns w ...