I'm creating a 3D game with XNA, and I'm stuck when I try to attach correctly a weapon to a bone.
You can see the result below :
The Image
So, the weapon follow the right hand, I just need to find a good rotation but this is not my problem.
My problem is : When I scale down the machete, its Y value decreases... Indeed, I think that XNA sets the position thanks to the center of mass of the mesh... I wanted to know if is it possible to modify this center of mass ? to draw my machete from the handle (I don't know if we can say that in this context).
I hope you will understand what my problem is :)
I apologize for my bad english, see you :)
When drawing the weapon you should do few matrix multiplicatins.
1) places the blade in center origin
2) resizes it
3) rotates it against local axis
4) places the blade in the wanted location.
The order of the multiplication matters! Multipliying in a different order will yield anoying results and displacements of the model.
Matrix transform = fixPosMat * Matrix.Scale(1.5f) * rotationMat * PositionMat;
I'm not sure to understand...
I draw my model thanks to this matrix :
boneLocal = Matrix.Invert(skinnedModel.SkeletonBones[index].InverseBindPoseTransform)
* animationController.SkinnedBoneTransforms[index]
* Matrix.CreateScale(scale)
* _rotation
* Matrix.CreateTranslation(_position);
Related
My name is Stanley and I need help :).
I am attempting to find the average rotation from an array of positions. (Stay with me here). If you are confused with what I mean, just like I am myself, then here is an example. I am making a boating game and there are raycast hits that find four points at each corner of the boat. In order to make the floating look realistic, I made it so that the average y position of all four points would be the y position of the boat. But the average rotation I cannot seem to figure out.
I have done some tests if there is a point at 0,0,0 and 1,1,0 and 0,1,1 the average rotation using xyz coordinates is -25,-25,50 and I can't seem to figure out the math behind it. (I eyeballed the final rotation in unity and it looks pretty spot on, that is how I got that number.) If anyone has seen anything about this online like an equation or way of solving this it would be a huge help.
Thanks Everyone
Stan.
I dont know whether I understood you correctly, but how exactly do u get an average rotation of (-25, -25, 50)? What I would do is (if the number of points are always three) create a plane, calculate the normal of that plane and trying to figure out what combination of rotation matrices lead to the corresponding components.
If your three points are (0,0,0), (1,1,0), (0,1,1) the corresponding plane's normal would be (-1, 1, -1), and from that you could deduce what the rotations must be in order to get a reference vector (lets say (1,0,0)) that satisfies R_X(a) * R_Y(b) * R_Z(c) * (1,0,0) = (-1, 1, -1)
But I guess thats not what you want, do you?
I created a Unity3d project and I used some spotlights behind objects to get their shadows. I'm trying to get the real size (using my scale) of the shadow once reflected on the floor. Is there a way to do that?
I do believe your question would mostly belong to Mathematics Stack Exchange but here's an approach that I hope will lead you to the right direction.
The hypotheses I took here are:
you know your object height when scale = 1
your object isn't too large on its top (or you will have to include half its width to the maths)
your object pivot is placed at it's base (on a human : under its feet)
your object is placed on the floor (and therefore not in the air: otherwise it's a bit more complicated to calculate but the idea remains the same)
Here's a quick schema of the situation:
Now you can calculate your shadow's size using something like this:
Vector3 topPoint = YOUR_OBJECT.transform.position + YOUR_OBJECT.transform.lossyScale.y * YOUR_OBJECT_HEIGHT;
Vector3 lightFlatPoint = new Vector3(YOUR_LIGHT.transform.position.x, topPoint.y, YOUR_LIGHT.transform.position.z);
float lightDeltaY = YOUR_LIGHT.transform.position.y - topPoint.y;
float lightFlatToTopPointDistance = Vector3.Distance(lightFlatPoint, topPoint);
float shadowSize = ((YOUR_OBJECT.transform.lossyScale.y * YOUR_OBJECT_HEIGHT) / lightDeltaY) * lightFlatToTopPointDistance;
Hope this helps,
I thought it would be simple as:
Vector3 point = Vector3.Transform(originalPoint, worldMatrix);
But apparently not... It make's the point's numbers shoot into the thousands.
Basically, what I'm trying to do is creating a collision system and every two points in this system is a line, so basically I want to collide lines. I want the lines to be able to scale, rotate, and translate based on a world matrix (so that the collision lines are in tune with the object's scale, rotation, and translation).
I've been trying for hours now and I can't seem to figure it out. I've tried multiplying by the View Matrix as well and while that is the closest to what I want, it seems to switching between two sets of numbers! It would be perfect if it stayed with the one set, I have no idea why it keeps changing...
Any help, please? :(
Edit: To add a little, I'm constantly updating the points in an Update call. But I don't know if that would change anything, either way the points = originalpoints first.
Steve H:
One line would have two points, so:
originalPoint[0] = new Vector3(-42.5f, 0f, 0f);
originalPoint[1] = new Vector3(42.5f, 0f, 0f);
point[0] = Vector3.Transform(originalPoint[0], worldMatrix);
point[1] = Vector3.Transform(originalPoint[1], worldMatrix);`
At first, point[0] & [1] equals the same as originalPoint[0] & [1]. But, the moment I move my player even just a few pixels...
point[0] = (-5782.5f, 0f, 0f)
point[1] = (-5697.5, 0f, 0f)
The player's position is -56.0f.
My worldMatrix goes as:
_world = Matrix.Identity // ISROT
* Matrix.CreateScale(_scale) // This object's scale
* Matrix.CreateFromQuaternion(_rotation) // It's rotation
* Matrix.CreateTranslation(_offset) // The offset from the centre
* Matrix.CreateFromQuaternion(_orbitRotation) // It's orbit around an object
* _orbitObjectWorld // The object to base this world from
* Matrix.CreateTranslation(_position); // This object's position
The objects display properly in graphics. They scale, rotate, translate completely fine. They follow the orbit's scale, rotation, and translation too but I haven't tested orbit much, yet.
I hope this is enough detail...
Edit: Upon further research, the original points are also being changed... :| I don't get why that's happening. They're the exact same as the new points...
I figured out my problem... -_-
So, after I create the line points, I do this at the end:
originalLines = collisionLines;
collisionLines & originalLines are both Vector3[] arrays.
I guess just by making one equal the other, it's like they're the exact same and changing one changes the other... that is something I did not know.
So I made this function:
void CreateOriginalPoints()
{
_originalPoints = new Vector3[_collisionPoints.Length];
for (int i = 0; i < _collisionPoints.Length; i++)
_originalPoints[i] = _collisionPoints[i];
}
And this solves the problem completely. It now makes complete sense to me why this problem was happening in the first place.
Thanks a lot Donnie & Steve H. I know you two didn't answer my question but it got me to poke around even deeper until I found the answer.
I'm a real noob who just started learning 3d programming and i have a really hard time learning about rotation in 3D space. My problem is that I can't seem to figure out how to rotate an object using it's local coordinates.
I have a basic class for 3d objects and, for starters, i want to implement functions that will rotate the object on a certain axis with x degrees. So far i have the following:
public void RollDeg(float angle)
{
this.rotation = Matrix4.Mult(rotation,
Matrix4.CreateRotationX(MyMath.Conversions.DegToRad(angle)));
}
public void PitchDeg(float angle)
{
this.rotation = Matrix4.Mult(rotation,
Matrix4.CreateRotationY(MyMath.Conversions.DegToRad(angle)));
}
public void YawDeg(float angle)
{
this.rotation = Matrix4.Mult(rotation,
Matrix4.CreateRotationZ(MyMath.Conversions.DegToRad(angle)));
}
'rotation' is a 4x4 matrix which starts as the identity matrix. Each time i want to roll/pitch/yaw the object, i call one of the functions above.
for drawing, i use another function that pushes a matrix onto the ModelView stack, multiplies it with the translation, rotation and scale matrices of the object (in this order) and begins drawing the vertices. ofcourse, finally i pop the matrix off the stack.
the problem is that the functions above rotate the object on the GLOBAL axis, not on the LOCAL ones, even if, from my understanding, every time you rotate an object, the local system changes it's axis and then, when a new rotation is applyied on top of the others, the local axis are used for the new one.
i read different tutorials about the math behind it and how to rotate objects, but i couldn't find one the could help me.
if anyone has the time, i would really appreciate if he could help me understand HOW to rotate around local axis and, maybe even more important, what i did wrong on my current implementation.
If you want to perform your transformations in this order : translation -> rotation -> scale (which makes perfectly sense, it's what's wanted usually), you have to multiply your matrices in the reverse order.
In a right-handed coordinate system (i.e. the one openGL uses), matrix multiplication must be performed from right to left. This is why :
ModelViewTransform = Transform * View * Model // <- you begin by the model, right ? so it's this way
Note that in directX they use a left-handed coordinate system. It has his shortcomings, but it's more intuitive.
I played around with it for a while, but I simply can't figure it out.
I made a tank that fires missiles, and when the missiles hit the walls, I want them to bounce off, but I want them to bounce off to the right angle.
Right now I haven't got any obstacles, the missiles just bounce off when they get outside the viewportRectangle I made.
Is the solution I'm looking for quite advanced?
Is there a relativly simple way to do it?
You might think that because your walls are aligned with the coordinate axes that it makes sense to write special case code (for a vertical wall, negate the x-coordinate of the velocity; for a horizontal wall, negate the y-coordinate of the velocity). However, once you've got the game working well with vertical and horizontal walls, probably the next thing you'll think is, "what about walls at arbitrary angles?" So it's worth thinking about the general case from the beginning.
In the general case, suppose your missile has velocity v and hits a wall with surface normal n.
Split v into components u perpendicular to the wall and w parallel to it.
Where:
u = (v · n / n · n) n
w = v − u
Here, v · n is the dot product of the vectors v and n. See the link for an explanation of how to compute it. The dot product n · n evaluates to the square of the length of the normal vector; if you always keep your normals in the form of unit vectors then n · n = 1 and you can omit the division.
After bouncing, the component of motion parallel to the wall is affected by friction f, and the component perpendicular to the wall is affected by elasticity, which can be given in the form of a coefficient of restitution r.
So the velocity after the collision is v′ = f w − r u. In a perfectly elastic, frictionless collision, v′ = w − u; that is, the motion is reflected about the normal at the point of collision, as in the diagram given in Bill's answer.
This approach works just the same in three dimensions too.
(Obviously this is a very simplified notion of bouncing; it takes no account of angular momentum or deformation. But for many kinds of video games this kind of simplification is perfectly adequate.)
I think an easier way to do this is to use the velocity of the missile instead of calculating angles. Say you have a missile that has xVelocity and yVelocity to represent its movement horizontally and vertically. Those velocities can be positive or negative to represent left, right, up, or down.
If a missile hits a top or bottom border reverse the sign of the yVelocity.
If a missile hits a left or right border reverse the sign of the xVelocity.
This will keep the movement in the opposite axis the same.
Borrowing the image from ChrisF's answer, let's say the missile starts out at position I.
With the xVelocity and yVelocity both being positive (in 2D graphics right and down are typically positive) the missile will travel in the direction indicated. Let's just assign values of
xVelocity = 3
yVelocity = 4
When the missile hits the wall at position C, its xVelocity shouldn't change, but its yVelocity should be reversed to -4 so that it travels back in the up direction, but keeps going to the right.
The benefit to this method is that you only need to keep track of a missile's xPosition, yPosition, xVelocity, and yVelocity. Using just these four components and your game's update rate, the missile will always get redrawn at the correct position. Once you get into more complicated obstacles that are not at straight angles or are moving, it will be a lot easier to work with X and Y velocities than with angles.
For perfect particles (& light) the angle of reflection is equal to the angle of incidence, as illustrated by this diagram (from commons.wikimedia.org).
The Wikipedia page on reflection is quite good at explaining how it works.
It's a little bit more complicated when you take into account the elasticity and materials of the object and the obstacles, but this is probably good enough for most applications.
I've had this problem, the only way I found was separating the axes of collision!
Try it:
x += velocity * Math.cos(angle * Math.PI /180);
y += velocity * Math.sin(angle * Math.PI /180);
if (x < 0 || x > canvas.width) {
angle = 180 - angle;
}
else if (y < 0 ||y > canvas.height) {
angle = 360 - angle;
}
I hope this helps you!
As an aside to the specific physics question you are asking, I would recommend the book "Beginning Math and Physics for Game Programmers" by Wendy Stahler. I found it quite useful for my game/physics programming projects.
The code that accompanies the book is C++ but if you know C#, it would be pretty easy to make the conversion.
Have a good one!
180-a will not work in all instances, unless you are merely working a bounce on a top surface when X is increasing.
One direction to head is the XNA forums or pick up XNA sample code. It is C# and it is for building games. I am not stating you want to build your games in XNA, but it is a great tool, and it is free.
Not complicated at all - pseudo-code:
angleObjectHitWall = a;
bounceAngle = 180-a;
Of course this is a very simple calculation, and is totally irrelevant once you start to take into account factors such as material, gravity, walls which aren't straight, etc...
This is really a physics question, so if you are not a physicist (and since you are asking this question, I'm going to take it that you are not) it will require a lot of reading and brainstorming to get it right.
I suggest reading this wikipedia entry to get the basic idea about the depth of your question.
If you only want to make it "look plausible" then I wouldn't worry about it too much and use Bill the Lizard's answer, however if you want to make it right you will have quite an adventure. Don't let this scare you tho! Good luck!
a = 2w - b
where:
a => resulting angle
w => wall or floor or ceiling angle
b => ball angle
This is what I come up after trying to find the simplest formula for computing just the resulting angle of ball bouncing the walls, ceiling and floor. The result could go beyond +360 or -360 degrees but they are still equivalent angle.For example if the ceiling angle is 270deg and the ball angle is 30deg, the resulting angle is 510deg which is equivalent to +150deg or -210 deg. If you'll use 90deg for the ceiling instead of 270deg, the result is still 150deg.
if(!Collide(Missle, Mainchar)){
(Velocity.x)*-1;
(Velocity.y)*-1;
}
It works and is simple, good luck.