THREE.js: making a skinned mesh follow a spline - javascript

I have a skinned mesh of a 'snake', exported from blender.
The snake has bones (like a spine) which I want to animate along a curve (SplineCurve3)
I can calculate points along the spline, and the angles between those points, but I'm struggling setting the rotations of the bones correctly.
The problem is that each bone is a child of the previous bone, so rotating one also rotates the others.
Here's an image:
The outer shape is the snake.
The pink line is a section of a SplineCurve3.
The blue/green lines are the bones (THREE.SkeletonHelper).
Each bone is rotated using SplineCurve3.getTangentAt. Because the parent is rotated too, the snake curls up. I basically need the bones to be where the pink line is.
How can I 'compensate' for the rotation of the parent(s) when calculating the rotation of a bone?
Also, in the image the path is flat, but my goal is to move the snake in 3 dimensions. It's a flying snake.

Can you clarify which rotation is which (maybe draw some angles and label them for reference)?
If the whole snake is at an angle to the axes, then just subtract that angle from the bone angle.
Surely, however, the bone angles are defined relative to the parent bone, not as absolute angles against the axes? If you are using the absolute angles subtended with the x-axis as relative angles, then that would produce the behaviour you see of increasingly rotated bones.
Assuming the bone angles should be given relative to the parent bone, then you want:
childRelativeAngle = childAbsoluteAngle - parentAbsoluteAngle

Related

Rotating around an arbitrary axis without changing its previous orientation

So i am simulating a foreward kinematic chain in Three.js. The chain contents of cylindrical joints and static links inbetween. The links are static and should only be rotated and translated according to the kinematics. I get displacement matrices M with some rotation and a positional vektor for the joints. The displacement matrix determines also the rotation and position of the following joints, but you have to add the cylindrical rotation and translation for the joint to be in the correct place.
function updateLink(link, jointAxis, trans, rot_3, rotOffset, transOffset){
pre_link = new Object3D()
pre_link = link.clone() //use the old link from zero configuration
pre_link.matrix.setFromMatrix3(rot_3) // change the position and rotation due to
// movement of the chain
pre_link.matrix.setPosition(trans)
pre_link.matrixAutoUpdate = false;
The translation is just the translational offset along the joint axis(which is nomalized) :
trans = anchor + transOffSet * jointAxis
https://i.stack.imgur.com/Ni5Xb.png
Now the link is at the bottom of the joint, but it needs to get rotated around the joint axis to get in place, while not effecting the rotation and translation it got from the displacement matrix.
I tried out a bunch of things , iE that i add the joint to the cylinder and then rotate the parent:
cylinder.add(link)
cylinder.rotateOnAxis(jointAxis, rotOffset)
With this code, the link gets rotated around an axis that goes through the origin, but i want to rotate around general lines not going thorugh the origin. (The cylinder up Axis, which is some kind of normalized vector at a certain point in the coordinate system.)
Any help or ideas would be much aprreciated.

THREE.js How to calculate rotation position on a 3D circle?

As represented in the image below, I have a THREE.Scene with a simple cube. Attached to the cube is a CANNON.Body for Physics (represented in the green wireframe).
The CANNON.Body is offset from the cube by a couple of units. For rotation, this offset will be the radius.
When I rotate the cube, I want the CANNON.Body to rotate around the cube based on the angle and radius. On the right hand side of the image, I rotated the cube with an angle of 45 degrees (I also have radians available). However, the CANNON.Body does not rotate around the cube, only around it's own center. I need it to rotate around the cube for all axes x, y and z.
Is there a built-in function in THREE.js or should I use my own mathematical equation for this? If so, what would that be?
Thanks!
P.S. I've seen solutions for pure THREE.js Scene's where the geometry is translated to manipulate the pivot point. Since I don't have geometry in my CANNON.Body, this will not be possible.
I never worked with cannonjs, but was it possible to just add the Cube and the Rigid Body in a Three.Group?
Like
var rigidBody = new CANNON.Body(); // whatever it is for cannon
var model = new THREE.Group();
// your model goes here
model.add(new THREE.Mesh(
new THREE.BoxGeometry(1,1,1),
new THREE.MeshStandardMaterial()
));
model.add(rigidBody);
scene.add(model);
This way, if you rotate the parent element model, the rigidbody should update the same way.

How do I determine when small object in front of big object and visible for camera?

I'm newbie in three.js and WebGL.
In my application, there is 3D scene in which the two objects.
object - it is a big sphere;
object - a smaller sphere, which is located on the surface of the first object.
Big sphere rotates around its axis. And also there is the possibility to rotate the camera around the spheres.
So as a small sphere on the surface of a large sphere, it also rotates with it. Small sphere will be visible to us as large sphere turns to the camera and it will not be visible when a large sphere is in front of it.
The question is, how do I determine when a small sphere is visible to the camera, and when it is not visible?
Also, I need to get the coordinates in 2d for small sphere where it is visible. How can I do this?
This can be accomplished with three.js's built-in raycaster and projector functionalities. To start, try taking a look at this demo and its source code. Here is another example. In this way you can determine which objects are closer to an invisible line that is emitted from the camera's position.
Otherwise, if you are simply interested in which of the two objects is closer to the camera, you can simply check to see which of their position values have a lesser distance to the camera's coordinates. The three-dimensional distance formula would come in handy:
bigSphereDistance = Math.sqrt( Math.pow(camera.position.x - big.position.x,2) +
Math.pow(camera.position.y - big.position.y,2) +
Math.pow(camera.position.z - big.position.z,2) );
smallSphereDistance = Math.sqrt( Math.pow(camera.position.x - small.position.x,2) +
Math.pow(camera.position.y - small.position.y,2) +
Math.pow(camera.position.z - small.position.z,2) );
//then check...
bigSphereDistance > smallSphereDistance ? /*case*/ : /*case*/;
Intuitively, the small sphere is visible when its distance is less than that of the big sphere, with a buffer of the small sphere's radius.
To answer your second question, finding any object's 2D coordinates can accomplished like this.

Rotation of a shape loaded with ObjLoader [duplicate]

When we add a CustomGeometry to the scene with defining vertices and not setting the position, how can we get it to rotate around its own center point?
Fiddle : http://jsfiddle.net/tezcancirakoglu/Ldt7z
In the sample code, object is rotating around Scenes X axis. I need to rotate it around its center point.
Hint: The red cube mesh is the initial centerpoint of the object which is rotating. I need to rotate it around x axis of red cube... I tried alot but failed anyway.
One solution is to translate the mesh geometry, and compensate by changing the mesh position, like so:
var offset = objMesh.centroid.clone();
objMesh.geometry.applyMatrix(new THREE.Matrix4().makeTranslation( -offset.x, -offset.y, -offset.z ) );
objMesh.position.copy( objMesh.centroid );
updated fiddle: http://jsfiddle.net/Ldt7z/165/
P.S. You do not need to save your fiddle before running it. There is no reason to have so many versions.
three.js r.55
You can use the center of the bounding box, which would basically be the 'average' of your vertices but it is not guaranteed to fall onto the red cube.

How can I find a set of coordinates relative to a rotation?

How can I find a position relative to a point that has been rotated? The idea is, that I'm rotating an entity at a certain position, and need to be able to find a position relative to that entity's rotation, such that 10 units above the entity relative to its rotation is different from 10 units directly above the entity. Hopefully this diagram should give you an idea of what I mean:
Note: I'm doing this in the <canvas> tag with pure Javascript.
Also note: I'm only just finishing Algebra, and have done just a little trigonometry and some geometry, so please make your explanation relatively clear. Sin, cos, and tangent are only just beginning to make sense, and I had to look up the concept of radians myself the other day in order to work with <canvas>'s rotation function (thanks, Wikipedia!).
Also also note: I have tried looking this up myself (Google, SO, elsewhere), but not knowing the proper terms, I wasn't able to find anything. I'm sure this must be fairly simple, but it may as well be Greek to me.
If all you're looking for is a point that is d units from a point (x,y) at an angle θ, where the angle is taken relative to the point as its origin, in the clockwise direction, from the positive y-axis, the point is given by (x + d*cos(π/2-θ), y + d*sin(π/2-θ))
You can do it with vectors and matrices.Let's say that the direction to the 25,10 is forward vector of your cube.So you can apply the rotation matrix to this vector ,that is multiplying this vector by rotation matrix which is rotated amount of degrees you need.That will return you your relative position.Hope it is clear.I am not JavaScript expert.But I am sure there is some Vector math API out there you can use.
You have to do these steps:
Calculate the vector from cubes position to your desired offset before the rotation.
Calculate rotation matrix with some rotation.
Multiply that vector by the rotation matrix to get the new rotated vector.
I found this JavaScript Vector math lib.Take a look at the Matrix object.It has a method for vector multiplication.
If you kow how to rotate the square, you know howto rotate the vector.
What you did with the square (25,25), do with the vector(25,15)

Categories

Resources