I'm working on Libdx app using Decals.
Decals are 2d sprites in 3d world.
I have problem that when I say:
decal.setRotationX(angle)
everything works fine, but when I say:
decal.setRotationX(angle);
decal.setRotationY(angle2);
The decal rotates over Y axis only.
How to manage that problem?
I have found that Decal in source code uses Quaternion for rotation, but currently I don't know how to customize that to face my requirements.
Tnx in advance!
EDIT:
I have managed to rotate decal around multiple axis with:
decal.getRotation().setEulerAngles(yaw,pitch,roll);
Now my question is how to animate this with TweenEngine?
In get values method I have:
returnValues[0] = target.getRotation().getYaw();
returnValues[1] = target.getRotation().getPitch();
returnValues[2] = target.getRotation().getRoll();
In set values method I have:
target.getRotation().setEulerAngles(newValues[0], newValues[1],
newValues[2]);
But decal is not moving or animating, it's stucked in one position (slightly rotated over XYZ axis).
Any idea, values in TweenEngine are correct but somehow decal is not refreshing and rotating.
If you want to do it only once, you can do it like this:
decal.rotateX(angleX);
decal.rotateY(angleY);
decal.rotateZ(angleZ);
This will "add" the given angle to the current one though.
An alternative way would be to use the rotation Quaternion of the Decal:
decal.getRotation().setEulerAngles(yaw, pitch, roll);
The following image shows what "yaw", "pitch" and "roll" means:
Roll, pitch, yaw http://i.msdn.microsoft.com/dynimg/IC79189.gif
EDIT: I've just seen the JavaDoc of Decal.getRotation() and it says that the returned quaternion should not be modified! I've also checked the code and every other method of Decal sets an internal update flag which will cause the decal to change the next time it's rendered. Decal.getRotation() does not set this flag and thus the changes to it won't get recognized.
It seems like currently there is no really clean and easy way to set the rotation on all three axes at the same time. A workaround might look like this:
decal.setRotationX(0);
decal.setRotationY(0);
decal.setRotationZ(0);
decal.rotateX(angleX);
decal.rotateY(angleY);
decal.rotateZ(angleZ);
It first resets all angles to 0 and then rotates on each axis while not overwriting any other axis.
Related
I am trying to create a 3D Visualization of an RC airplane in Threebox. The RC plane sends live telemetry, including:
GPS Coordinates
Gyro sensor data, showing the pitch, roll and heading of the plane.
I have now loaded a Model of an airplane in Threebox, no problems with that.
My problem comes down to the rotation of the plane. I want the plane object to represent the current orientation of the RC plane. Since I have the live telemetry from the flight controller, this should be possible.
In the Documentation, I have found this method, which seemed like exactly what i needed:
plane.setRotation({x: roll, y: pitch, z: yaw/heading})
And it basically works. I can rotate the Plane around its axes. But things get messed up when I combine the rotations.
For example: When I just update the roll axis, the Object behaves just like I want it to. However, when i change the heading of the plane by 90 degrees, the roll axis suddenly becomes the pitch axis. It seems to me, that the axes of the Plane object don't rotate with the plane itself.
I've prepared a recreation of the issue on jsfiddle. You can change the heading of the plane using the slider in the bottom right.
I've been stuck on this for days, would be super happy for any help!
There are lots of issues with your jsfiddle that prevent it from running. To isolate an issue and make it easier to test you should eliminate as many variables as possible - you're using two third-party libraries that will play a big hand in how transformations behave, particularly threebox.
I would recommend sticking with three.js's built in transformation tools unless you specifically need some lat/lng transformations, or other transformations to move between a local cartesian space and a global coordinate system. In this case, a very basic plane.setRotationFromEuler(new THREE.Euler(yaw, pitch, roll)) should do the trick. Be aware of how much order in euler rotations can affect the outcome, and that three.js uses radians for all its rotations, not degrees.
for a personal project, I've created a simple 3D engine in python using as little libraries as possible. I did what I wanted - I am able to render simple polygons, and have a movable camera. However, there is a problem:
I implemented a simple flat shader, but in order for it to work, I need to know the camera location (the camera is my light source). However, the problem is that I have no way of knowing the camera's location in the world space. At any point, I am able to display my view matrix, but I am unsure about how to extract the camera's location from it, especially after I rotate the camera. Here is a screenshot of my engine with the view matrix. The camera has not been rotated yet and it is very simple to extract its location (0, 1, 4).
However, upon moving the camera to a point between the X and Z axes and pointing it upwards (and staying at the same height), the view matrix changes to this:
It is obvious now that the last column cannot be taken directly to determine the camera location (it should be something like (4,1,4) on the last picture).
I have tried a lot of math, but I can't figure out the way to determine the camera x,y,z location from the view matrix. I will appreciate any and all help in solving this, as it seems to be a simple problem, yet whose solution eludes me. Thank you.
EDIT:
I was advised to transform a vertex (0,0,0,1) by my view matrix. This, however, does not work. See the example (the vertex obviously is not located at the printed coordinates):
Just take the transform of the vector (0,0,0,1) with the modelview matrix: Which is simply the rightmost column of the modelview matrix.
EDIT: #ampersander: I wonder why you're trying to work with the camera location in the first place, if you assume the source of illumination to be located at the camera's position. In that case, just be aware, that in OpenGL there is no such thing as a camera, and in fact, what the "view" transform does, is move everything in the world around so that where you assume your camera to be ends up at the coordinate origin (0,0,0).
Or in other words: After the modelview transform, the transformed vertex position is in fact the vector from the camera to the vertex, in view space. Which means that for your assumed illumination calculation the direction toward the light source, is the negative vertex position. Take that, normalize it to unit length and stick it into the illumination term.
I'm making a 3d dice game and came to one issue I can't wrap my head around so I'm turning to you for help.
In the scene/world (using threejs with cannonjs) I have a plane and one die, which I'm throwing on the plane (screenshots here pre-roll http://prntscr.com/l9rat5, result http://prntscr.com/l9rdeb). All works fine, until I want to throw some specific value on a die like 1 for example.
Since I'm using loaded models instead of texture images for faces of the cube, I cannot handle this just by changing faces of the cube in threejs (since model has 100s of them). Therefore I was hoping I can achieve this by somehow changing the initial quaternion of the body (kind of pre-rotate it) so the die falls on a specific side. The die mesh is just following the body position and quaternion.
I have these questions:
Is this even possible to do? Maybe when I change quaternion pre throw it will result always in different final quaternion, which I can not determine? If it is not possible to do with quaternions, any tips?
If it is possible, how do I figure out by which quaternion do I need to multiply my initial one to get desired result value 1? I have available the final quaternion and I know which values are on each face from emulated throw so I was trying to play with quaternion inverse but no luck.
If I just rotate the initial body so that face 1 rotates to the result face (eg. 6) it works in some cases (i throw 1 when emulated result was 6), but when the throw gets more complicated (more rotations) it is not working of course since I'm not counting on all possible rotations.
If it is not clear what I mean let me know pls.
Thanks a lot
m
First of all, make sure that you use fixed step simulation. You do this by passing 3 arguments to world.step() instead of one. This will make sure that your simulation will behave the same every time, regardless of frame rate.
Also make sure that your initial position, velocity and force of the die is the same every throw.
If you construct the quaternion using the built in cannon functions, like .setFromAxisAngle(), all should be good... Use .setFromAxisAngle() with even 90-degree angles around different axis. Why bother using quaternion inverse?
If you want an alternative way of rotating the die, put the mesh below an empty parent mesh in your scene. During simulation, copy the cannon.js output to the parent mesh. Then rotate the child die mesh to get the desired initial (and end) rotation.
For the note, I solved it by rotating just the geometry (not mesh) in threejs and not touching the quaternion of the body at all.
I'm working app that uses Libgdx engine and decals in 3d space.
Now I need to rotate decals around X,Y,Z axis, but around custom pivot point that stands somewhere in the 3d space.
I found that decals have transformationOffset field, which might work with some calculations, but is Vector2 only. It means that I can move pivot point only over X and Y axis.
And when rotating decals over Y axis, wherever the pivot is, the result is the same.
decal.transformationOffset = new Vector2(0, -5);
decal.rotateX(newValues[0]);
decal.rotateY(newValues[1]);
decal.rotateZ(newValues[2]);
I need to move pivot over Z axis, too.
Is there some workaround for this issue?
Tnx!
EDIT:
I have succeded to rotate decal over pivot point in 3d space, but only if pivot's and decals's Z position is the same. If they are not I don't get what I've expected.
This is the code that works for pivot with same Z value:
decal.transformationOffset = new Vector2(pivotPosition.x - decal.getPosition().x, pivotPosition.y - decal.getPosition().y);
Tween.to(decal, DecalTween.XYZ_ROTATION, 5f).target(0, 360, 0).repeatYoyo(Tween.INFINITY, 0f).start(tweenManager);
And in tween I do this:
target.setRotationX(0);
target.setRotationY(0);
target.setRotationZ(0);
target.rotateX(newValues[0]);
target.rotateY(newValues[1]);
target.rotateZ(newValues[2]);
How to extend this to use and Z value for pivot. I'm trying to add and translation animation beside rotate to achive this, but the results is weird.
Tween.to(decal, DecalTween.MOVE_XYZ, 2.5f).target(decal.getPosition().x, decal.getPosition().y, pivotPosition.z - decal.getPosition().z).repeatYoyo(Tween.INFINITY, 0f).start(tweenManager);
decal.transformationOffset = new Vector2(pivotPosition.x - decal.getPosition().x, pivotPosition.y - decal.getPosition().y);
Tween.to(decal, DecalTween.XYZ_ROTATION, 5f).target(0, 360, 0).repeatYoyo(Tween.INFINITY, 0f).start(tweenManager);
Any idea how to combine translate and rotate animatio to get decal rotation in circle path over the pivot point?
I will answer my own question I guess.
I have extended Decal class, changed transformationOffset to Vector3.
Then in transformVertices I have added tz value, like there already was tx and ty. And add tz in calculation for vertex position.
Simple as that.
If anyone knows why is this left out from native libgdx support, please let me know.
Cheers.
I'm a fresh in cocos3d, now I have a problem.
In cocos3d, I want to rotate a node. I got the angles in x axis, y axis, z axis, then I used the property:rotation to rotate, like this:
theNodeToBeRotated.rotation = cc3v(x,y,z);
But I found out it didn't rotate as I expected, because the document said the rotate order is y-x-z.
I want to change the order to x-y-z. Can anyone let me know how?
You might need to clarify further regarding the following: "it didn't rotate as I expected"
OpenGL ES (and ergo, cocos3D) uses the y-axis as up so the rotation order is still x-y-z. If you are importing a model, you then need to take into account the 3D editor's co-ordinate system and adapt accordingly.
If you are not used to working with three-dimensional representations, the leap from 2D to 3D can be a significant hurdle. Within Cocos3D:
the x-axis is positive on the right and negative on the left
the y-axis is positive upwards and negative downwards
the z-axis is positive moving towards you and negative moving away from you
Envisage those three lines of axis, or even better, a piece of string.
If you are rotating around the x-axis, hold the string horizontally from left to right: the object would rotating towards you or away from you.
If you are rotating around the y-axis, hold the string vertically from feet to head: the object would rotate as if like a revolving door.
If you are rotating around the z-axis, hold one end close to your chest and the other end as far away as possible: the object would rotate similar to a clock face.
-- Update
I heavily wouldn't recommend changing the rotation order as it is the OpenGL standard to use Y-X-Z. If you wish to modify it, take a look at CC3GLMatrixMath and look for kmMat4RotationYXZ - there is also kmMat4RotationZYX. If you want to have X-Y-Z, you would need to construct your own rotation matrix and update accordingly in CC3GLMatrix and CC3GLMatrixMath.
As a reference, you also have the OpenGL Red book - it should have some suggestions for you.