Achieve the buoyancy effect in threejs to make an object float on water

I successfully created a water effect using THREE.WATER and incorporated a few gltf objects into the scene. Currently, I am aiming to make these added objects float on the water just like a boat would.

Below is the code snippet:

var scene, camera, renderer, ambient, directional, controls, stats, clock, imageLoader;
var terrain, water, mixer, model, modelL;

...

function loadBar() {
    // Function implementation here
}

function generateTexture() {
    // Function implementation here
}

function loadLilly(coord){
    // Function implementation here
}

function loadFrog() {
    // Function implementation here
}

function loadPlant() {
    // Function implementation here
}

function loadWater() {
    // Function implementation here
}

function animate() {
    // Function implementation here
}
<body>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <style>
        /* Styles for body, canvas, #question, .score, .pause */
    </style>
    <div id="question">
    </div>
    <span class="score">
        <h1>23</h1>
    </span>
    <script src="https://threejs.org/build/three.js"></script>
    <script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/loaders/GLTFLoader.js"></script>
    <script src="https://rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>
    <script src="https://rawgit.com/mrdoob/three.js/master/examples/js/objects/Water.js"></script>
    <script src="index.js"></script>
</body>

The current loadLilly() function loads lily pads onto the water surface, but I need them to actually float on the water. Here's a reference link to the lily pad object:

I've attempted to adjust the position with obje.position.y but it hasn't yielded the desired outcome. Any assistance in resolving this issue would be greatly appreciated.

Thank you.

Answer №1

One approach is to load the lilly model once and then utilize its geometry and material within a loop to create a new mesh for each lilly.

In this scenario, I have demonstrated creating the lilly's geometry and material directly in the code.

The floating effect is achieved using the sin function on the y-coordinate. This concept can be extended to make lillies move along any coordinate axis.

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 100);
camera.position.set(0, 2.5, 5);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

var light = new THREE.DirectionalLight(0xffffff, 1);
light.position.setScalar(1);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.5));

scene.add(new THREE.GridHelper(10, 100, "aqua", "aqua"));

// Define lilly geometry
let lCurve = new THREE.EllipseCurve(0, 0, 1, 1, 0, 1.9 * Math.PI);
let lPts = lCurve.getPoints(32);
lPts.push(new THREE.Vector2());
let lShape = new THREE.Shape(lPts);
let lGeom = new THREE.ExtrudeBufferGeometry(lShape, {
  depth: 0.25,
  bevelEnabled: false
});
lGeom.rotateX(-Math.PI * 0.5);
lGeom.translate(0, -0.125, 0);
let lMat = new THREE.MeshLambertMaterial({
  color: "green"
});

// Create lillies
var lillies = [];
var lillyCoordPosition = [
  [-2.5, -2.5],
  [0, -2.5],
  [2.5, -2.5],
  [-2.5, 0],
  [0, 0],
  [2.5, 0],
  [-2.5, 2.5],
  [0, 2.5],
  [2.5, 2.5]
].forEach(p => {
  let l = new THREE.Mesh(lGeom, lMat);
  l.position.set(p[0], 0, p[1]);
  l.rotation.y = Math.random() * Math.PI * 2; // random rotation
  let s = Math.random() * 0.25 + 0.75; // slightly different size of each one
  l.scale.set(s, 1, s);
  l.userData.initFloating = Math.random() * Math.PI * 2; // initial value for start of floating
  lillies.push(l);
  scene.add(l);
});

var clock = new THREE.Clock();

renderer.setAnimationLoop(al);

function al() {
  let t = clock.getElapsedTime();
  lillies.forEach(lil => {
    lil.position.y = Math.sin(lil.userData.initFloating + t) * 0.05;
  });
  renderer.render(scene, camera);
}
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

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

What is the best method for transmitting the filename using Plupload?

I've been trying to solve this issue for a while now. My problem seems straightforward – I want to send the filename along with the file as a multipart request in Plupload, but so far, I haven't had any success. The main thing I'm missin ...

Combining two items from separate arrays

How can I efficiently merge objects that share the same index in two different arrays of objects? Below is the first array const countries = [ { "name": "Sweden", "nativeName": "Sverige" }, ...

The value within the style.setProperty function does not get applied

I have a progress bar that dynamically increases based on user input: <div class="progressBarContainer percentBar"> <div class="progressBarPercent" style="--width:${gPercent}" id="${gName}-pbar">< ...

Executing a Javascript Function within AngularJS

I encountered an issue where the error myFunction() IS NOT DEFINED is appearing: app.controller('myctrl',function(){ myFunction(); }); function myFunction() { debugger; document.getElementById("abc").disabled = false; } In this sce ...

Load content from a drop-down menu selection into a div using AJAX

I have a customized Drop Down menu that serves as a navigation tool on my website. The drop down is designed using JavaScript and CSS to achieve the desired style and functionality. Each link in the drop down has been assigned numerical values, and a speci ...

Finding the orientation of a Rubik's Cube may seem like a daunting task at

Currently, I am working on developing a Rubik's Cube game in WebGL using Three.js, which you can try out here. I am facing difficulties in determining the correct axis for rotating the cube based on its current orientation. For example, when the cube ...

Unable to activate click function in Jquery

Here is a basic HTML page snippet: <html> <head> <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"> </script> <script> $(document).ready(function () { $('#test').click(); }); < ...

Storing newly generated rows using PHP and JavaScript

In my form, I have dynamically added rows that work properly. Once the user fills in the form fields and clicks on the "check correctness" submit button, validation is performed. If the data is incorrect, a correction is required. If the data is correct, a ...

What's the best way to handle the output of an HTTP request in my specific situation?

Struggling to pass http request results from parent controller to child controller... This is what I have: <div ng-controller = "parentCtrl"> <button ng-click="callApi()">click me</button> <div ng-controller = "childCtrl"& ...

Using jQuery to transfer array values to a different group of elements

Looking for help with this code snippet: jQuery(document).ready(function($) { var i = 0; var values = []; var element = $('.source'); element.each(function(i) { values[i++] = $(this).text(); }); }); I'm tryi ...

Revamping password security using token-based password reset system

As I work on the password reset feature for my authentication application, I have decided to utilize JWT, node.js, and express. Here's my approach: First, the user enters their email, triggering the generation of a token that is then sent to the user& ...

Save picture in localStorage

Hello, I am currently working on a page where I need to retrieve an image from a JSON file and store it locally. Below is the code I have been using: <!DOCTYPE html> <html> <head> <script src="http://code.jquery.com/jquery-1.10.1.min. ...

The issue arises when jQuery stops functioning properly following the second ajax call

I'm encountering an issue with my ajax request in asp.net mvc. It works fine for the first and second time, but then it redirects to a page instead of fetching the page via ajax. Below is the code snippet for my partial page: <script> var ...

What strategies can be implemented to effectively share code between these two methods?

Is there a way to consolidate code shared between these two JavaScript methods? async getAllActiveRooms(ctx: ?ContextType): Promise<RoomType[]> { //log getAllActiveRooms return this.i.knex('users_rooms') .transacting(ctx ...

Highlighting a row upon being clicked

How can I implement a feature in my HTML page that highlights a row when selected by changing the row color to #DFDFDF? If another row is selected, I would like the previously selected row to return to its original color and the newly selected row to be h ...

Toggle class on element based on presence of class on another element

If I have 4 boxes and the user is required to choose one. I aim to assign an active class to the box that the user clicks on. However, if the user selects another box, I want to remove the class from the first clicked box and apply it to the newly clicked ...

Encountering a 403 error while using the ajax infinite loading script

Based on recommendations from my previous inquiry, I made the decision to incorporate an infinite loading script onto my page. However, every time the script is activated, a 403 - forbidden error occurs. Here is the JavaScript code snippet: jQuery(documen ...

Creating dynamic rows for Firebase data in React BootstrapTable can be accomplished by dynamically rendering each row

Hey everyone, I'm currently working on a web app project where I am creating a table. Below is the code snippet for it: class Table1 extends Component { render() { return ( <div> <BootstrapTable data={this.props.data}> ...

Preventing an iframe from reloading when transferring it to a new parent using appendChild

I'm looking to relocate an iframe to a different parent element while maintaining the iframe's current state (including scroll position and any entered form data). Unfortunately, when I use appendChild() to move the iframe, it reloads and resets ...

JS await function does not wait for the completion of the request

https://i.sstatic.net/weCy0.png async function updateData(){ let stickTimes = []; await request(terryRink, function (err, res, body) { if(err) { console.log(err, "error occurred while hitting URL"); } else { le ...