Rotate mesh in 3D via mouse, and have it accelerate

In the link below I extracted the relevant code for my game(To reassure you, I plan to import models instead of the ugly placeholder that will scar your gaming soul for all of eternity once I make them.):
https://playground.babylonjs.com/#KIXTXN#1
I’ve been stuck for weeks on how to do the following two things:

  1. Rotate the mesh “fighterMesh” and its physics imposter in 3D based off of a mouseMove event listener, or maybe the canvas controls.
  2. Apply constant acceleration to “fighterMesh” and its physics imposter in the direction its facing in such a way that I can toggle it.

Some other things seem to be amiss as well, but they’re all minor. I feel confident I could figure out the rest.
And as you can probably see, the code is BEYOND slapped together. So if you have any suggestions to streamline it, please let me know.
Thanks in advance for any help.

Hey @BlockDoc23,

Instead of using setTimeout, you should try using scene.onBeforeRenderObservable to ensure you only update once per frame. See this gameloop pg: https://playground.babylonjs.com/#15EY4F#0

For applying constant force try this: https://www.babylonjs-playground.com/#BEFOO#363

For camera rotation/movement see this https://playground.babylonjs.com/ts.html#0ZP9MH#4

For mousemovement maybe this thread will help Firefox pointerlock + mousemove + mousedown behavior

Thanks @trevordev for spotting the mistake with my camera with the interval.
However, I’m currently looking at the other links you sent though, and it doesn’t look like what I’m looking for.
For the constant force, I don’t know how to apply the force to the mesh locally instead of via world (hence why the documentation drove me nuts). The cube in the example you sent me doesn’t move towards its own up, but rather the scene’s/world’s up.
The camera being locked the way it is with the “scene.onBeforeRenderObservable” is fine with me, or perhaps better, but I still need a way to move the fighter fluidly with the mouse. When I come back at this tomorrow, I’ll try adding angular velocity locally via mouse event, with dampening of some kind. (maybe current / .995 = new or something, in the scene.onBeforeRenderObservable).
Anyways, I updated the playground to include the locked camera, but not the force input. Also, when I tried it, said force input broke the velocity of my fighterMesh.

https://playground.babylonjs.com/#KIXTXN#3

Sorry in advanceI won’t be able to respond again until tomorrow, or maybe even later. So take your time.

To convert the force vector/position in this case you can transform the downward vector by the object’s rotation matrix

For rotation you can update it on mousemove with scene.onPointerObservable

see https://www.babylonjs-playground.com/#BEFOO#365

Here’s a more manageable scene:

https://www.babylonjs-playground.com/#BEFOO#366

Galen

Thank you both so much, @trevordev and @Galen! The scene is actually running now!
But I do have questions. If I didn’t understand the code I put in my program, then I wouldn’t be able to modify it effectively, should the need arise.
Here is the updated scene:
https://playground.babylonjs.com/#KIXTXN#4
I understand how the pointer movement works, but not why it doesn’t locally convert. Moving the mouse up or to the side is recorded, divided by 1000, then applied to the mesh. Wonderful. But when I move the mouse, sometimes the fighterMesh moves the wrong way. After playing with the camera, I found that the rotation is done to the fighterMesh too perfectly. I LOVE the fact that the fourth Quaternion rotates freely, but…the camera’s doesn’t.
Can I allow the camera to rotate along its own fourth Quaternion freely (locking it to the fighter’s), and ensure that the camera/canvas/page down is the same as the fighter somehow? Am I able to set the fourth Quaternion of the camera in the loop below?

scene.onBeforeRenderObservable.add(()=>{camera.position = cameraBoi.getAbsolutePosition();});

I’m sorry for all the trouble. BABYLON.JS is so amazing that it’s hard to find the needle of what you want in the proverbial haystack of its documentation. Having said that, this is the least toxic community I’ve seen in years. Thanks again!

Perhaps the behavior you’re looking for is in the camera movement. There are many options to control this. Here are the docs:

https://doc.babylonjs.com/how_to/camera_behaviors

Galen

Unfortunately, I don’t think I see any of these working for fixing the “w” in the camera’s (x,y,z,w) Quaternion. It’s probably hidden deep in the bowels of the API or documentation. Is there a way to use the “FlyCamera” or part of it to input the fighter’s universal roll, aka the “w” in its quaternion, as the camera’s own before every render?
https://doc.babylonjs.com/babylon101/cameras#flycamera
This “FlyCamera” is the first time I’ve seen a BJS camera not be perfectly right-side-up. But it banks as an interaction, and not the way I think would be useful.
Or maybe, in the onBeforeRenderObservable loop, I record the new camera position, find the fighterMesh’s “w”, and input the new rotation? I don’t even know at this point. There has to something I’m overlooking, like a “camera.Quaternion.w = fighterMesh.Quaternion.w” or something. I’m also hoping that once this is fixed, the camera won’t shift around anymore away from the fighterMesh.

Have you tried to parent your camera to a mesh? Then you can manipulate the mesh anyway you like. You will need to set up the controls manually for this, but it can have many advantages. I’ve often found limitations to camera behaviors, but not to meshes.

Galen

I tried that, and got the error “Line 16:921646 - e.subtract is not a function”.
I have no idea what that means, but I do know it means I done goofed somehow. Here’s a link to what I ended up with in the playground.
https://playground.babylonjs.com/#KIXTXN#5
I tried the Universal and Free cameras, just in case, but the error is preventing the scene from rendering.
Is a partial parenting possible? Or are we barking up the wrong tree entirely, and is the mesh rotating with respect to the world and not itself? I see no indication of this other than the “ToRef” in “FromEulerVectorToRef.”
Good idea, @Galen, but the execution is lost on me. Let me know if you can find where I went wrong.

No I assume it’s not a function. You need to create a function specifically for what you need and use the event manager to pass the event to this function when the event happens.

Here’s a PG that might help on a very basic level.

https://www.babylonjs-playground.com/#Y1W3F9

Galen

Notice the error is character #921646 on line 16. I never put “e.subtract” in my code (not to mention I don’t have that many characters in line 16), it’s an error for BJS because I used improper syntax somewhere. I’ve gotten these errors before, and only fixed them when I found something like mixing up BABYLON.Mesh and BABYLON.MeshBuilder meshes, and stuff like that.

In other words, I didn’t phrase myself clearly before. The error means that somewhere I violate a rule of BJS, and not that I used e.subtract. Sorry about the confusion.

Perhaps this will help…

You might try passing your values through a JQuery wrapper. Otherwise it’s easy to make an error in the DOM.

Galen

line 120 - setTarget is not a method on UniversalCamera - see UniversalCamera - Babylon.js Documentation

try the property lockedTarget

Thanks, @JohnK. That was it. But then I got the background screen of death…aka an empty scene. I feel like parenting the camera would work, but the scene below says otherwise…
https://playground.babylonjs.com/#KIXTXN#7
I feel helpless. Every time something works, it breaks down.
However, if we use the playground below from before, is there a way to set the camera’s upVector in accordance to the fighterMesh’s X or Z? If so, then all that would be left is the camera drift.
https://playground.babylonjs.com/#KIXTXN#4

I may have got it completely wrong but it seems to me that your scene view of the fighter is always constant, in which case you may be better off using overlapping scenes one for the view of the fighter and the apparent mouse control of the fighter is actually controlling the camera view of the another scene, the one the fighter is supposed to be in?

I’m going to give that a shot when I get the chance, it seems like a good solution. Just to clarify, though, if I create the scene serverside and the player data clientside, will I be able to:

Generate projectile particles from the camera?
Have controls cause acceleration instead of velocity?
Allow other players to see a “fighterMesh” where the camera is (by setting its position to just behind the camera, maybe)?
Have said camera interact with the scene via the fighterMesh physics imposter?
Allow rotation about the “w” Quaternion coordinate freely (eg get rid of the camera’s idea of “up,” maybe by setting it’s upVector to null or something)?

I don’t necessarily need help with these yet, I haven’t and currently can’t try them on my own. But I don’t want to use this method of rendering if it will cause problems down the line.
Take your time getting back to me, my schedule will prevent me from looking at this for another few days, maybe even a week. But also, thanks to you three @JohnK @trevordev @Galen, I got farther than I would have on my own. Thanks a lot, and I wish I could give something back.

I think you have this the wrong way round. Although I have never done anything multiplayer as far as I understand it

  • for anything to be viewable by a player the whole (viewable part of the) scene has to be generated clientside after downloading from the server
  • data such as player position, player angle etc have to be transferred backwards and forwards between the server and local computer and all data synchronised between players

This means that anything you can do locally with BJS you can do via a server (since the player has to have everything on their local machine) it is just more difficult.