Xna ModelBones - How to move them away from eachother? - vector

Hello I know that one can get absolute transforms of bones in a model.. But how to move them away (like inflating) ? I think to do so, I need to move them forward to their local positions but what I have is the absolute transfoms by
Model.CopyAbsoluteBoneTransformsTo(ModelAllTransforms);
How to proceed further ? I mean I can use
mesh.ParentBone.Transform = Matrix.CreateTranslation(?) * ModelAllTransforms;
but what would be the ? sign ..
Thanks a lot! :)

The direction you're looking for is basically the local bone's absolute transform minus the center, then normalized.
Something like this:
//"time" is your timing value, "speed" is some float value
Vector3 direction = bone.Translation - center;
direction.Normalize();
Vector3 translate = time * speed * direction;
bone.Translation += translate;

Related

Find RayCast Vector and move away from it in Godot

I am making a game in Godot and I want one of my enemies to move away from the ground when it detects a collision with RayCasts.
I set up my RayCasts like this:
I tried using this code:
for i in dodge.get_children():
if i.is_colliding():
var velocity = Vector2().rotated(deg2rad(i.rotation_degrees))
move_and_collide(velocity * -charge_speed * delta)
Where dodge holds all the RayCasts and I go through all its children and check for collisions. I then tried rotating the Vector2 by the rotation of the RayCasts, since that is how I rotated them instead of using Cast To, and tried moving it by that Vector, but it didn't work. It didn't even move in the wrong direction. It didn't move at all.
How would I go about solving this?
Look at this line:
var velocity = Vector2().rotated(deg2rad(i.rotation_degrees))
Here you create a new Vector with Vector2(). Which is equivalent to Vector2(0.0, 0.0).
When you rotate Vector2(0.0, 0.0), regardless of the angle, it will remain Vector2(0.0, 0.0).
As a result velocity will be Vector2(0.0, 0.0).
Then in this line you scale velocity:
move_and_collide(velocity * -charge_speed * delta)
If you multiply zero, I mean Vector2(0.0, 0.0), by any number it is still Vector2(0.0, 0.0).
And so it will move according to Vector2(0.0, 0.0), i.e. not at all.
So you need to change that starting Vector2(). It could be Vector.RIGHT or Vector.UP, or more likely Vector.DOWN. How do you know? Well, it is the direction of the RayCast2D if you don't rotate them.
Or, alternatively, you could use cast_to also. I believe it is like this:
var velocity = i.global_transform.basis_xform(i.cast_to).normalized()
Using basis_xform should apply the rotation (and any skewing), but not the translation. I also added normalized because I don't know if the result will be an unit vector, so it is to make sure it is.

Moving a object based on its rotation in three.js

I'm trying to move a cube in three.js based on its rotation but not sure on how to go about it.
As of now I can rotate the cube's z-rotation with the A & D keys. And with the W key I would like it to move forward relative to its rotation.
From 2D I would so something along the lines of:
float angle = GradToRad(obj.rotation);
obj.x = obj.x + cos(angle) * velocity;
obj.y = obj.y + sin(angle) * velocity;
Here's an image of the current implementation.
How can I apply something similar in three.js?
Objects can be considered to be facing their positive-Z axis. So to move an object forward, relative to it's own coordinate system, you can use
Object3D.translateZ( distance );
three.js r.57
It might be easiest to express both rotation and translation in a single (homogenous projective) 4×4 matrix. The Object3D.matrix member in three.js already does that, although you might have to set matrixAutoUpdate to false to use that directly. Then you can move use the translate method to move the object in its own reference frame.
Your 2D method is exactly how I did it in three.js. For the Y position I'm using a terrain collision technique (which still needs work);

openGL - I want the camera to get closer to the object, how?

I used the Qt equivalent to the gluLookAt to set my view matrix and I've been moving it by translating it everywhere in the scene.. now I want to get close with the camera to an object.
I know the position of the object, both in object coords and in each other coords (I have the model matrix for that object), but how to get the position of the camera?
To animate the camera to get closer and closer to the object I suppose I should take two points:
The point where the object is
The point where the camera is
and then do something like
QVector3D direction_to_get_closer = point_where_object_is - point_where_camera_is
How do I get the point where the camera is? Or, alternatively if this is not needed, how do I get the vector to the direction the camera has to follow (no rotations, I just need translations, this is going to simplify things) to reach the object?
gluLookAt(eye, target, headUp) takes three parameters, the position of the camera/eye, the position of the object you want to look at, and a unitvector to controll roll/head up direction.
To zoom closer, you can move the eye/camera position by some fraction of your vector direction_to_get_closer. For instance,
point_where_camera_is += 0.1f * direction_to_get_closer; // move 10% closer
Its more useful to move by a constant amount instead of 10% of the current distance (or else you will move very fast when the distance is great, and then increasingly slower). Therefore, you should use the normalized direction:
QVector3D unitDir = direction_to_get_closer.normalized();
point_where_camera_is += 0.1f * unitDir; // move 0.1 units in direction
The camera transform will break if point_where_camera_is becomes equal to point_where_object_is.
A better way, if you don't need to zoom, translate/rotate the new "zoomed" point_where_camera_is is to interpolate between to positions.
float t = some user input value between 0 and 1 (0% to 100% of the line camToObj)
QVector3D point_on_line_cam_obj = t * point_where_camera_is + (1-t) * point_where_object_is;
This way, you can stop the user from zooming into the object by limiting t, also, you can go back to the start position with t=0;

How to move point along circle?

I want to move a sprite in a circular motion by using a circle radius and movingangle.
I know for instance that the sprite is moving in a circle with the radius 10 and It's current position is (387,38) and angle is 28 degrees. Now I wann't move it say, 100px along the circle perimeter.
p1 = x&y coordinate, known (387,38) in example with movingangle 28 degrees
r = radius, known (10 in example)
l = distance to move along bend, known (100px in example)
p2 = new point, what is this x and y value?
I have a solution that works but I dont quite like it. It kind of don't make sense to me and it requires more calculations than I think is required. It works by first calculating the center point using p1 and then doing the same thing backwards so to speak to get p2 (using cosinus and sinus). There should be a quicker way I believe but I cant find anyone doing exactly this.
The reason i tagged cocos2d is because thats what I'm working with and sometimes game frameworks provide functions to help with the trigonometry.
Try this:
a1 = 28*(π/180)
cen.x = p1.x - r*SIN(a1)
cen.y = p2.y - r*COS(a1)
a2 = a1 + l/r
p2.x = cen.x + r*SIN(a2)
p2.y = cen.y + r*COS(a2)
It does not get any simpler than this. Move from p1 to the circle center, and then to p2.
You can do it with magic of anchor point in a really simple way =) All the transformations with any node are done relatieve to it's anchor point. Rotation is a kind of transformations too. So, you can do something like this
CGFloat anchorY = neededRadius / spriteHeight;
[yourSprite setAnchorPoint:ccp(0.5f, anchorY)];
[yourSprite setPosition:neededPosition]; //remember that position is also for anchor point
[self addChild: yourSprite];
[yourSprite runAction:anyRotateAction]; // i mean, CCRotateBy or CCRotateTo
Calculate the origin, and then use polar co-ordinates to move the point along the circle.

How to get Yaw, Pitch and Roll from a 3D vector

I have a direction vector that applied to a position gives me the point at which the camera should look. How can I get from that yaw, pitch and roll in order to use glRotatef properly?
Thanks in advance
None of these equations are 'wrong' but all are a little clumsy.
Ryder052, you example does not account certain cases as you've commented. Why not use atan2?
Given unit (normalized) direction vector d
pitch = asin(-d.Y);
yaw = atan2(d.X, d.Z)
You cannot get yaw, pitch and roll from a direction vector as the direction vector will only tell which direction to look in (yaw and pitch)
To get the yaw and pitch you use trigonometry - I assume you have some working knowledge. Check out this wiki page for some useful diagrams to visualize the angles.
Letting Y = yaw, P = pitch.
First to get yaw you want:
tan(Y) = x/(-y)
Now to get pitch:
tan(P) = sqrt(x^2 + y^2)/z
To get the actual values for Y and P you'll need to use inverse tan, I've written it above using tan to make the derivation clearer.
Note that the minus signs depend on how you define you angles and axes, but you should get the idea.
You can then set roll to be 0 or whatever you like.
You probably don't actually want the yaw, pitch and roll. You just need the correct transformation. Try using gluLookAt to build it. Documentation.
pheelicks's equations are wrong. Dear future googlers, here you got what's working:
Assuming pitch: rotation by X axis, yaw: rotation by Y axis, roll: rotation by Z axis. Direction vector V(x,y,z)
pitch = asin(V.y / length(V));
yaw = asin( V.x / (cos(pitch)*length(V)) ); //Beware cos(pitch)==0, catch this exception!
roll = 0;
Well, I am not sure what any of these answers are about because I could not get any of them to work.
I created my own solution...
// get world target offset
// convert world target offset to world direction normal
// get my world transposed (inverted)
// rotate world direction normal to my space normal
Vector3D lWorldTargetOffset = gWorldTargetLocation - gWorldMyLocation;
Vector3D lWorldTargetDirection = lWorldTargetOffset.Normalize();
MatrixD lMyWorldTransposed = MatrixD.Transpose(MyWorldMatrix);
Vector3D lMySpaceTargetDirection = Vector3D.Rotate(lWorldTargetDirection, lMyWorldTransposed);
you now have the world target direction normal in my space
lMySpaceTargetDirection.X = pitch
lMySpaceTargetDirection.Y = yaw.
lMySpaceTargetDirection.Z = <0 infront >0 behind.
As per direction normals all values are -1 to 1 so if you want degrees simply * 90.
Not saying this is the best solution but it is the only one I could get to work after spending hours searching online and wading through copious amounts of obtuse and nebulous crud.
I hope you, someone, or anyone, will enjoy simply rotating the target direction normal making it relative to myspace, and find it easy and helpful :)

Resources