最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - threeJS move object from point A to point B - Stack Overflow

programmeradmin4浏览0评论

i saw some questions on SO but i still don't get how to do a simple animation like that.

Basicly i just want to move the object from point A to point b, i already did some job where i applied the translate but the object keep moving without stopping, i need my scene to coninue animating.

At the moment i have this code:

import { Component, ViewChild, ElementRef, OnInit } from '@angular/core';
import * as THREE from 'three';
import * as dama from "./dama.json";


const VIEW = {
  angle: 45,
  aspect: screen.width / screen.height,
  near: 0.1,
  far: 1000
}

const matrix = {
  numberPieces: 15,
  brownField: [
    // first row
    {x: -5.95, y: 10, z: 3.95},
    {x: -2.75, y: 10, z: 3.95},
    {x: 0.45, y: 10, z: 3.95},
    {x: 3.6, y: 10, z: 3.95},
    {x: 6.8, y: 10, z: 3.95},
    //second row
    {x: -7.5, y: 10, z: 5.55},
    {x: -4.35, y: 10, z: 5.55},
    {x: -1.15, y: 10, z: 5.55},
    {x: 2, y: 10, z: 5.55},
    {x: 5.15, y: 10, z: 5.55},
    //third row
    {x: -5.95, y: 10, z: 7.15},
    {x: -2.75, y: 10, z: 7.15},
    {x: 0.45, y: 10, z: 7.15},
    {x: 3.6, y: 10, z: 7.15},
    {x: 6.8, y: 10, z: 7.15}

  ],
  blackField: 
  [
    // first row
    {x: -5.95, y: 10, z: -7.2},
    {x: -2.75, y: 10, z: -7.2},
    {x: 0.45, y: 10, z: -7.2},
    {x: 3.6, y: 10, z: -7.2},
    {x: 6.8, y: 10, z: -7.2},
    //second row
    {x: -7.5, y: 10, z: -5.6},
    {x: -4.35, y: 10, z: -5.6},
    {x: -1.15, y: 10, z: -5.6},
    {x: 2, y: 10, z: -5.6},
    {x: 5.15, y: 10, z: -5.6},
    //third row
    {x: -5.95, y: 10, z: -4},
    {x: -2.75, y: 10, z: -4},
    {x: 0.45, y: 10, z: -4},
    {x: 3.6, y: 10, z: -4},
    {x: 6.8, y: 10, z: -4},
  ]
}

@Component({
  selector: 'app-root',
  templateUrl: './appponent.html',
  styleUrls: ['./appponent.css']
})
export class AppComponent implements OnInit {
  private container: HTMLElement;

  @ViewChild('container') elementRef: ElementRef;
  private scene: THREE.Scene;
  private camera: THREE.PerspectiveCamera;
  private renderer: THREE.WebGLRenderer;

  private cube: THREE.Mesh;

  ngOnInit() {
    this.container = this.elementRef.nativeElement;

    this.init();
  }

  init() {
    let screen = {
      width: window.innerWidth,
      height: window.innerHeight,
      color: 0xffffff
    }

    this.scene = new THREE.Scene();
    this.renderer = new THREE.WebGLRenderer();
    this.renderer.setClearColor(0x000000, 1);

    this.renderer.setSize(screen.width, screen.height);
    this.container.appendChild(this.renderer.domElement);
    this.initCamera()
    this.initLights();
    var gameBoard = null;

    const sceneCtx = this.scene;
    const boardLoader = new THREE.JSONLoader();

    /**
     * Here we load the game board
     */
    boardLoader.load("assets/dama.json", (geometry, materials) => {
      gameBoard = new THREE.Mesh(geometry, materials);
      sceneCtx.add(gameBoard);
    });

    this.initPieces();

    this.render();
  }

  render() {

    let self: AppComponent = this;

    (function render() {
      requestAnimationFrame(render);
      self.renderer.render(self.scene, self.camera);
      self.renderer.setClearColor(0xffffff, 1);

      self.animate();
    }());

  }

  onResize(event) {
    this.renderer.setSize(window.innerWidth, window.innerHeight);
  }

  animate() {
    let piece = this.scene.getObjectByName("black-1");

    piece.translateZ(0.1);
  }

  initPieces() {
    const blackPieceLoader = new THREE.JSONLoader();
    const brownPieceLoader = new THREE.JSONLoader();

    const ctx = this;
    let brownPiece = null;
    let blackPiece = null;

    // we load here all the black pieces
    blackPieceLoader.load("assets/black.json", (geometry, materials) => {
      for(let i = 0; i < matrix.numberPieces;i++) {
        blackPiece = new THREE.Mesh(geometry, materials);
        blackPiece.position.set(matrix.blackField[i].x, matrix.blackField[i].y, matrix.blackField[i].z);
        blackPiece.name = "black" + "-" + i;
        ctx.scene.add(blackPiece);
      }
    });

    // we load here all the brown pieces
    brownPieceLoader.load("assets/brown.json", (geometry, materials) => {
      for(let i = 0; i < matrix.numberPieces;i++) {
        brownPiece = new THREE.Mesh(geometry, materials);
        brownPiece.position.set(matrix.brownField[i].x, matrix.brownField[i].y, matrix.brownField[i].z);
        brownPiece.name = "brown" + "-" + i;
        ctx.scene.add(brownPiece);
      }
    });
  }

  initLights() {
    var light = new THREE.AmbientLight(0xffffff);
    this.scene.add(light);
  }

  initCamera() {
    this.camera = new THREE.PerspectiveCamera(VIEW.angle, VIEW.aspect, VIEW.near, VIEW.far);    
    this.scene.add(this.camera);
    this.scene.add(new THREE.AxisHelper(20));
    this.camera.position.set(0, 35, 0);
    this.camera.lookAt(new THREE.Vector3(0, 0, 0));
  }

}

inside the animate i want to move a single object from point a to point B, for test the point b can be anything, the A point is the current position from the object that i assinged a name when i created him on the for loop:

important part

  animate() {
    let piece = this.scene.getObjectByName("black-1");

    piece.translateZ(0.1);
  }

i saw some questions on SO but i still don't get how to do a simple animation like that.

Basicly i just want to move the object from point A to point b, i already did some job where i applied the translate but the object keep moving without stopping, i need my scene to coninue animating.

At the moment i have this code:

import { Component, ViewChild, ElementRef, OnInit } from '@angular/core';
import * as THREE from 'three';
import * as dama from "./dama.json";


const VIEW = {
  angle: 45,
  aspect: screen.width / screen.height,
  near: 0.1,
  far: 1000
}

const matrix = {
  numberPieces: 15,
  brownField: [
    // first row
    {x: -5.95, y: 10, z: 3.95},
    {x: -2.75, y: 10, z: 3.95},
    {x: 0.45, y: 10, z: 3.95},
    {x: 3.6, y: 10, z: 3.95},
    {x: 6.8, y: 10, z: 3.95},
    //second row
    {x: -7.5, y: 10, z: 5.55},
    {x: -4.35, y: 10, z: 5.55},
    {x: -1.15, y: 10, z: 5.55},
    {x: 2, y: 10, z: 5.55},
    {x: 5.15, y: 10, z: 5.55},
    //third row
    {x: -5.95, y: 10, z: 7.15},
    {x: -2.75, y: 10, z: 7.15},
    {x: 0.45, y: 10, z: 7.15},
    {x: 3.6, y: 10, z: 7.15},
    {x: 6.8, y: 10, z: 7.15}

  ],
  blackField: 
  [
    // first row
    {x: -5.95, y: 10, z: -7.2},
    {x: -2.75, y: 10, z: -7.2},
    {x: 0.45, y: 10, z: -7.2},
    {x: 3.6, y: 10, z: -7.2},
    {x: 6.8, y: 10, z: -7.2},
    //second row
    {x: -7.5, y: 10, z: -5.6},
    {x: -4.35, y: 10, z: -5.6},
    {x: -1.15, y: 10, z: -5.6},
    {x: 2, y: 10, z: -5.6},
    {x: 5.15, y: 10, z: -5.6},
    //third row
    {x: -5.95, y: 10, z: -4},
    {x: -2.75, y: 10, z: -4},
    {x: 0.45, y: 10, z: -4},
    {x: 3.6, y: 10, z: -4},
    {x: 6.8, y: 10, z: -4},
  ]
}

@Component({
  selector: 'app-root',
  templateUrl: './app.ponent.html',
  styleUrls: ['./app.ponent.css']
})
export class AppComponent implements OnInit {
  private container: HTMLElement;

  @ViewChild('container') elementRef: ElementRef;
  private scene: THREE.Scene;
  private camera: THREE.PerspectiveCamera;
  private renderer: THREE.WebGLRenderer;

  private cube: THREE.Mesh;

  ngOnInit() {
    this.container = this.elementRef.nativeElement;

    this.init();
  }

  init() {
    let screen = {
      width: window.innerWidth,
      height: window.innerHeight,
      color: 0xffffff
    }

    this.scene = new THREE.Scene();
    this.renderer = new THREE.WebGLRenderer();
    this.renderer.setClearColor(0x000000, 1);

    this.renderer.setSize(screen.width, screen.height);
    this.container.appendChild(this.renderer.domElement);
    this.initCamera()
    this.initLights();
    var gameBoard = null;

    const sceneCtx = this.scene;
    const boardLoader = new THREE.JSONLoader();

    /**
     * Here we load the game board
     */
    boardLoader.load("assets/dama.json", (geometry, materials) => {
      gameBoard = new THREE.Mesh(geometry, materials);
      sceneCtx.add(gameBoard);
    });

    this.initPieces();

    this.render();
  }

  render() {

    let self: AppComponent = this;

    (function render() {
      requestAnimationFrame(render);
      self.renderer.render(self.scene, self.camera);
      self.renderer.setClearColor(0xffffff, 1);

      self.animate();
    }());

  }

  onResize(event) {
    this.renderer.setSize(window.innerWidth, window.innerHeight);
  }

  animate() {
    let piece = this.scene.getObjectByName("black-1");

    piece.translateZ(0.1);
  }

  initPieces() {
    const blackPieceLoader = new THREE.JSONLoader();
    const brownPieceLoader = new THREE.JSONLoader();

    const ctx = this;
    let brownPiece = null;
    let blackPiece = null;

    // we load here all the black pieces
    blackPieceLoader.load("assets/black.json", (geometry, materials) => {
      for(let i = 0; i < matrix.numberPieces;i++) {
        blackPiece = new THREE.Mesh(geometry, materials);
        blackPiece.position.set(matrix.blackField[i].x, matrix.blackField[i].y, matrix.blackField[i].z);
        blackPiece.name = "black" + "-" + i;
        ctx.scene.add(blackPiece);
      }
    });

    // we load here all the brown pieces
    brownPieceLoader.load("assets/brown.json", (geometry, materials) => {
      for(let i = 0; i < matrix.numberPieces;i++) {
        brownPiece = new THREE.Mesh(geometry, materials);
        brownPiece.position.set(matrix.brownField[i].x, matrix.brownField[i].y, matrix.brownField[i].z);
        brownPiece.name = "brown" + "-" + i;
        ctx.scene.add(brownPiece);
      }
    });
  }

  initLights() {
    var light = new THREE.AmbientLight(0xffffff);
    this.scene.add(light);
  }

  initCamera() {
    this.camera = new THREE.PerspectiveCamera(VIEW.angle, VIEW.aspect, VIEW.near, VIEW.far);    
    this.scene.add(this.camera);
    this.scene.add(new THREE.AxisHelper(20));
    this.camera.position.set(0, 35, 0);
    this.camera.lookAt(new THREE.Vector3(0, 0, 0));
  }

}

inside the animate i want to move a single object from point a to point B, for test the point b can be anything, the A point is the current position from the object that i assinged a name when i created him on the for loop:

important part

  animate() {
    let piece = this.scene.getObjectByName("black-1");

    piece.translateZ(0.1);
  }
Share Improve this question asked Dec 9, 2017 at 22:35 costa costacosta costa 1992 gold badges3 silver badges11 bronze badges 2
  • Referring to the THREE.Object3D docs, can't you just do piece.position.set(0, 1, 2)? Your current code seems very close... are you seeing errors or something? – Don McCurdy Commented Dec 10, 2017 at 0:33
  • Or to use Tween.js – prisoner849 Commented Dec 10, 2017 at 0:44
Add a ment  | 

1 Answer 1

Reset to default 17

You can use linear interpolation to move something from A to B. The generic formula is:

p = a + (b - a) * t

where t is in the range [0.0, 1.0]. You would apply this to each of the axis (x, y, z) you need to animate.

t can for example be bound to time which is remended as a constant frame rate can't be guaranteed in a browser environment, or to frames which is useful for non-realtime rendering.

t bound to time

For time you could calculate t the following way:

var startTime;
var duration = 2000;              // milliseconds

function loop(currentTime) {
  if (!startTime) startTime = currentTime;
  var t = (currentTime - startTime) / duration;
  // use t here, optionally clamp and/or add conditions
  requestAnimationFrame(loop);    // provides current high-res time as argument
}

t bound to frames

For a per-frame approach you can calculate t like this:

var fps = 60;
var duration = 2.0;               // seconds
var step = 1 / (duration * fps);  // t-step per frame
var t = 0;

... loop here
t += step;

You can of course also run t through easing functions before passing it to lerp to make smoother appearing transitions.

Basic Example for lerp()

var scene, renderer, cam, mesh;

// linear interpolation function
function lerp(a, b, t) {return a + (b - a) * t}

var t = 0, dt = 0.02,                   // t (dt delta for demo)
    a = {x: -2, y: -1, z: -1},          // start position
    b = {x: 1.5, y: 0.5, z: 0.7};       // end position
    
function loop() {
  var newX = lerp(a.x, b.x, ease(t));   // interpolate between a and b where
  var newY = lerp(a.y, b.y, ease(t));   // t is first passed through a easing
  var newZ = lerp(a.z, b.z, ease(t));   // function in this example.
  mesh.position.set(newX, newY, newZ);  // set new position
  t += dt;
  if (t <= 0 || t >=1) dt = -dt;        // ping-pong for demo
  renderer.render(scene, cam);
  requestAnimationFrame(loop)
}

// example easing function (quadInOut, see link above)
function ease(t) { return t<0.5 ? 2*t*t : -1+(4-2*t)*t}

// setup scene
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer();
cam = new THREE.PerspectiveCamera(40, innerWidth / innerHeight, 1, 50);
mesh = new THREE.Mesh(new THREE.BoxBufferGeometry(), new THREE.MeshBasicMaterial());
renderer.setPixelRatio(devicePixelRatio);
renderer.setSize(innerWidth, innerHeight);
cam.position.z = 5;
document.body.appendChild(renderer.domElement);
scene.add(mesh);
loop();
<script src="https://cdnjs.cloudflare./ajax/libs/three.js/88/three.min.js"></script>

发布评论

评论列表(0)

  1. 暂无评论