A-frame move forward in camera direction

為{幸葍}努か 提交于 2020-02-23 04:36:05

问题


I'm trying to make a component in A-frame that will move the player/camera in the direction the camera is facing. It should not move anywhere on the y plane, only in the x/y plane. The current setup in the dom is:

<a-entity>
    <a-camera></a-camera>
</a-entity>

I want to move the entity element position to x units in the current camera direction but it should not move anything on the y-plane. I have tried various solutions but they seem to introduce some weird shift in the camera.


回答1:


You could handle this in multiple ways.

0) Vectors

Simple and available in most 3D engines:

  • Grab the camera's forward vector / world direction
  • multiply it by the distance you want to move
  • add it to your position vector

The above steps within an a-frame component could look like this:

// inside an a-frame component
var player = document.querySelector("a-camera")    
var direction = new THREE.Vector3();
window.addEventListener("keydown", (e) => {
  if (e.code === "KeyR") {
     // get the cameras world direction
     this.el.sceneEl.camera.getWorldDirection( direction );
     direction.multiplyScalar(0.1)
     // faster than the below code - but getAttribute wont work
     // player.object3D.position.add(direction)
     var pos = player.getAttribute("position")
     pos.x += direction.x
     pos.y += direction.y // comment this to get 2D movement
     pos.z += direction.z
     player.setAttribute("position", pos);
   }
})

each time "R" is pressed I do the mentioned steps and move forward. You can see how this works in this fiddle.

However you may want to do this a bit more "math-ish" way:

1) 2D - Polar Coordinates

Mapping angles to 2D space is a job for the polar coordinate system !

We want to calculate x/y coordinates based on the camera rotation. The coordinate conversion looks like this:

x = r * cos(a)
y = r * sin(a)

where "r" is the step, the "a" is the angle.


Theory is boring, so lets get to practice:
       var angle = player.getAttribute("rotation")
       var x = 1 * Math.cos(angle.y * Math.PI / 180)
       var y = 1 * Math.sin(angle.y * Math.PI / 180)
       var pos = player.getAttribute("position")
       pos.x -= y;
       pos.z -= x;
       player.setAttribute("position", pos);

It's quite simple - get the angle, calculate the shift, and set the new position.

Check it out here.

2) 3D - Spherical coordinates

After all, this is a 3D space we're talking about.
The concept is the same - converting the camera angles into the x/y/z coordinates. The nifty trick here are the conversions from the spherical coordinate system.Three dimensions make it a bit more difficult, but the most confusing thing - the axis are different in the spherical system, than in the clipspace(used by a-frame):

Keeping that in mind the calculations should look like this:

// same component as 2D - just different calculations
var angle = player.getAttribute("rotation")
// the cameras 0 is actually 90' in the clipspace
let theta = (angle.x * Math.PI / 180) + Math.PI / 2
let fi = angle.y * Math.PI / 180
let r = 0.1
let z = Math.sin(theta) * Math.cos(fi) * r
let x = Math.sin(theta) * Math.sin(fi) * r
let y = Math.cos(theta) * r

var pos = player.getAttribute("position")
pos.x -= x;
pos.y -= y;
pos.z -= z;
player.setAttribute("position", pos);

Check it out in this fiddle.



来源:https://stackoverflow.com/questions/48726018/a-frame-move-forward-in-camera-direction

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!