user2168336 user2168336 - 16 days ago 6
Javascript Question

Dynamically replacing one mesh with another new mesh in three.js

I am trying to create a breakout game where the paddle is shaped like a piece of roof trim which is determined by the pitch of the roof. Hitting special bricks changes the pitch variable. Increasing or decreasing the pitch changes the "steepness" of the paddle.
The problem is when a pitch change occurs it draws a new paddle but still keeps the old one on the screen. As you can see on the screen shot there are 5 paddles of varying pitches on the screen after hitting 5 special bricks when there should only be one.

//Break out game with changing paddle shape

var gridSize=50;
var geometry;
var extrudeSettings;
var startPitch = 1;
var pitch = startPitch;
var pitchChange = false;
var paddle;
var paddleWidth = run*2;
var paddleX = 0;
var paddleLineThickness = .5;
var paddleMat = new THREE.MeshLambertMaterial({color: "purple"});
var paddleShape = new THREE.Shape();
var side = 10;
var pi = Math.PI;


function definePaddleShape() {
roofAngle = Math.atan(pitch/12);
rise = side*Math.sin(roofAngle);
run = side*Math.cos(roofAngle);
paddleWidth = run*2;
paddleShape.moveTo( -run, 0 );
paddleShape.lineTo( -run, paddleLineThickness );
paddleShape.lineTo(0, rise + paddleLineThickness );
paddleShape.lineTo( run, paddleLineThickness );
paddleShape.lineTo( run, 0 );
paddleShape.lineTo( 0, rise );
extrudeSettings = {amount:4, steps: 1, bevelSegments:0, bevelSize:0, bevelThickness:0};
}

function drawPaddle() {
geometry = new THREE.ExtrudeGeometry(paddleShape, extrudeSettings);
paddle = new THREE.Mesh(geometry, paddleMat);
paddle.castShadow = true;
scene.add(paddle);
paddle.rotateX(-pi/2);
paddle.translateY(-gridSize);
paddle.translateX(paddleX);
}


function draw() {
requestAnimationFrame(draw);

// pitch gets changed when a collision
// between ball and special brick occurs
// sets pitchChange to true

if(pitchChange) {
scene.remove(paddle);
definePaddleShape();
drawPaddle();
pitchChange = false;
}


renderer.render(scene, camera);
}


definePaddleShape();
drawPaddle();
document.addEventListener("mousemove", mouseMoveHandler, false);
draw();


enter image description here

Answer

you can initialize your paddle mesh in the init() function and then, in the drawPaddle() function you will just update the geometry of the paddle, like so:

function drawPaddle() {
    geometry = new THREE.ExtrudeGeometry(paddleShape, extrudeSettings);
    geometry.rotateX(-pi/2);
    //
    paddle.geometry.dispose();
    paddle.geometry = geometry;
    //
    paddle.castShadow = true;
    //scene.add(paddle); // you don't need it as you have the paddle mesh added already in init()
    paddle.translateY(-gridSize);
    paddle.translateX(paddleX);
}

Such technique used for examples of geometries on threejs.org

jsfiddle example