Jump to content

Vector3.RotateTowards Function


Recommended Posts

Hey guys... Well this time I need a Babylon equivalent function of the Unity Vector3.RotateTowards:

public static Vector3 RotateTowards(Vector3 current, Vector3 target, float maxRadiansDelta, float maxMagnitudeDelta);

Rotates a vector current towards target.

The current vector will be rotated round toward the target direction by an angle of maxRadiansDelta, although it will land exactly on the target rather than overshoot. 
If the magnitudes of current and target are different then the magnitude of the result will be linearly interpolated during the rotation. 
If a negative value is used for maxRadiansDelta, the vector will rotate away from target/ until it is pointing in exactly the opposite direction, then stop.

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    public Transform target;
    public float speed;
    void Update() {
        Vector3 targetDir = target.position - transform.position;
        float step = speed * Time.deltaTime;

        Vector3 newDir = Vector3.RotateTowards(transform.forward, targetDir, step, 0.0F);
        Debug.DrawRay(transform.position, newDir, Color.red);
        transform.rotation = Quaternion.LookRotation(newDir);

I have something similar inlace I use to 'LookAt' for a mesh... but I need to be able to do this on a vector itself:

public lookAt(position:BABYLON.Vector3, slerp:number = 0.0, yawCor?: number, pitchCor?: number, rollCor?: number, space?: BABYLON.Space):BABYLON.AbstractMesh {
    var result:BABYLON.AbstractMesh = null;
    if (this._owned != null) {
        if (this._owned.rotationQuaternion == null) this._owned.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(this._owned.rotation.y, this._owned.rotation.x, this._owned.rotation.z);
        if (this.slerpIdentity != null && slerp > 0.0) this.slerpIdentity.copyFrom(this._owned.rotationQuaternion);
        result = this._owned.lookAt(position, yawCor, pitchCor, rollCor, space);
        if (this.slerpIdentity != null && slerp > 0.0) BABYLON.Quaternion.SlerpToRef(this.slerpIdentity, this._owned.rotationQuaternion, slerp, this._owned.rotationQuaternion)
    return result;

Anyways I need to add a Vector Helper function to Rotate a Vector toward a target direction overtime (or slerping I guess)...

Yo @Deltakosh ... Any thoughts :)

I am basically trying to handle 'Basic Movement And Rotation' for a character (not even animated ... Just plain ol movement)...

Since I ONLY have unity as a source (I don't have ANY access to any Babylon Source or samples that really go into the WHOLE character movement).

Granted there a plenty of playgrounds with a guy moving ... but nothing that really outlines all the steps you need to make a full character ... Walking, running jumping etc...

Unless you already know how to do all stuff in Babylon  you gotta learn somewhere... So I have no choice but to use the 'Unity Tutorials' on how you do stuff like move things around, animations etc... So I don't mean to ask so many "HOW DO YOU DO THIS IN BABYLON" questions based from unity snippets :(

I am basically trying to get my guy to move FORWARD from the direction I am facing... if I just try use horizontal and vertical values for the movement vector:

this.moveVector.x = this.horizontalInput;
this.moveVector.y = 0.0;
this.moveVector.z = this.verticalInput;

and I am actually rotated a bit... the guy still goes (world forward I guess).. It should go strait ahead to the direction I am facing when pressing forward... But it kinda of faces the direction I wanna go but still GLIDES to the direction I was going before I slightly rotated it... Anyways all the unity examples for basic movement take into account

the mesh(transform) Forward and Right Direction...  SCALE those by vert and horz input (magnitude) and ADD those to together to get 'targetDirection'

THEN rotate the current moveDirection using Vector3.RotateTowards to the targetDirection over time... What I got so far...But need an Implementation of Vector3.RotateTowards

if (this._isCharacterGrounded === true) {
    var deltaTime:number = this.manager.deltaTime;
    var transformForward:BABYLON.Vector3 = BABYLON.Vector3.Forward();

    var transformRight:BABYLON.Vector3 = BABYLON.Vector3.Right();

    var targetDirection:BABYLON.Vector3 = transformForward.add(transformRight);

    this.moveDirection = Vector3.RotateTowards(this.moveDirection, targetDirection, 200 * BABYLON.Constants.Deg2Rad * deltaTime, 1000);
    this.moveDirection.y = 0.0;

    this.moveVector = this.moveDirection.scale(deltaTime * 2);
    this.moveVector.y = 0.0;

    if (targetDirection != BABYLON.Vector3.Zero()) {
        this.character.lookAtPosition(this.moveDirection, 0.2);

    //this.moveVector.x = this.horizontalInput;
    //this.moveVector.y = 0.0;
    //this.moveVector.z = this.verticalInput;

    this.manager.transformDirectionToRef(this.mesh, this.moveVector, this.moveVector);
    if (this.moveVector.length() > 1.0) BABYLON.Vector3.NormalizeToRef(this.moveVector, this.moveVector);
    this.moveVector.scaleInPlace(this.moveSpeed * BABYLON.Constants.VelocityFactor);

   // Note: Uses imposter.setLinearVelocity(this.moveVector);


Link to comment
Share on other sites

I think I still need a RotateTowards equivalent function... But I think my angle movement has to do with the cannons physics imposter not being able to move at that precise angle (say 30degress)... unless I am using setLinearVelocity wrong... Dunno... But I change to use move with mesh.position and it goes perfectly strait and the angle I am facing... What up with that... anybody know ???


Link to comment
Share on other sites

Hi M.  Not sure if this is the correct way, but I'll show it anyway.

Let's visit the physics-active white box in the middle of the flying bobsled.


The main active keys here... are SHIFTED arrows along-with SHIFTED page-up/down (to translate), and CONTROL arrows along-with CONTROL page-up/down (to rotate).  It uses micro-pulsings, so you hold-down these keys for a few seconds... to get the bobsled moving.  All-Stop is not working at this time, so reload to get the bobsled stopped, or impulse it to a stop.

To the point: 

1.  Hold control and tap/hold pageUP or pageDOWN... to get a Y-axis (yaw) rotation started.
2.  While rotation is still happening, hold shift and tap/hold up/down arrows.
(Try to alternate shift UP and DOWN arrows to move the flyer forward and backward in small amounts.)
3.  Notice that, no matter the rotation of the bobsled... shifted up-arrow ALWAYS moves the bobsled local +z.  The bobsled ALWAYS knows its "forward".

Next, lets look at the +z translation func in lines 131-143.  Borrow this func for your movePlayerForward func.  Looks pretty standard except for one thing... the call to doTransformPerFlyerQuat() in line 137.  The magic func is at line 158... and you should borrow that, too, and rename it to doTransformPerMeshQuat(). 

The "forward" of the bobsled... is based upon its .rotationQuaternion.  Deltakosh gave me that special and helpful function... to make this happen.  With the help of these two funcs, I think you can get your player to +z thrust/impulse exactly "forward" direction, no matter what.

I don't know if it is "the best way", but it has sure worked well for the flyer.  You can control-pageUp/pageDown the flyer into a serious yaw-spin, or ANY spin... and it never loses track of its "forward".  transPositiveZ() never gets confused, nor do any of the other translation funcs.  They all "honor" (take into consideration)the .rotationQuaternion in determining WHAT IS forward/backward, left/right, or up/down.  Perhaps this will help your tests.  I hope so.

Link to comment
Share on other sites

Holy Shit @Wingnut ...thats what you gotta do to move with 'AppyImpuse' and NOT directly setting the Linear Velocity... Wow... I am gonna have to study whats going there... But thanks for code... I can at least take at look at whats going on there... So its not just simple as 'SetPosition' to this or add 'this' to velocity ... Looks like some work needs to be done use physics as your movement...

Just to clarify... Using mesh.position.addInPlace(moveVector) IS WRONG and I should not be moving something that has a physics state with .position but use 'Impulse' instead ???


Link to comment
Share on other sites

No, no... you can use setLinearVelocity instead of applyImpulse... not a problem.  They're pretty much interchangeable, other than applyImpulse allows adjustment of the contact point on the mesh.  I just DIDN'T use setLinearVelocity in MY mover. 

I used dual-impulses for turning instead of setAngularVelocity, too.  Either way, works.  The main thing is the transform func.  Its returned value can be used for impulse or setLinearVelocity.

Plus, I didn't say anything was WRONG.  Somebody once said that it might be wise to use a joint between the mover and the moved.   No reason to freak.  I just told what I heard, and showed you what I once used in a project.  *shrug* 

I sure didn't mean to cause you any dismay.  I'm not a killer programmer.  Sorry.  Just trying to help in some little way. 

But it is my lame opinion that .rotateTowards is not an appropriate func for vector3's or Quaternions.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...