Author Topic: [SOLVED] Relative Vector Problems  (Read 1650 times)

Fix has been found!
Apparently looking as much up as you can made the vector slightly backwards, resulting in the entire calculation going wrong.
This is the end result:
Code: [Select]
function relativeVector(%dir, %vec)
{
%x = getWord(%vec, 0);
%y = getWord(%vec, 1);
%z = getWord(%vec, 2);

%relYvec = vectorNormalize(%dir);
%relYx = getWord(%relYvec, 0);
if (%relYx < 0)
%relYx *= -1;
%relYy = getWord(%relYvec, 1);
if (%relYy < 0)
%relYy *= -1;

if (%relYx < 0.00001 && %relYy < 0.00001)
{
%relYvec2 = vectorNormalize(vectorScale((getWord(%relYvec, 0) SPC getWord(%relYvec, 1) SPC "0"), -1));
%relXvec = vectorNormalize(vectorCross(%relYvec2, "0 0 1"));
%relZvec = vectorNormalize(vectorCross(%relXvec, %relYvec));
}
else
{
%relXvec = vectorNormalize(vectorCross(%relYvec, "0 0 1"));
%relZvec = vectorNormalize(vectorCross(%relXvec, %relYvec));
}
%relVec = vectorAdd(vectorAdd(vectorScale(%relYvec, %y), vectorScale(%relZvec, %z)), vectorScale(%relXvec, %x));
return %relVec;
}
Please note that the fix is only really relevant in this situation where you try to get a relative vector to the eyepoint and the player is looking so much up it is actually slightly backwards.
Very specific, but i had to fix it. :X
Use the above code if you want, no credits needed or anything, just USE IT.


Original problem and fix and the last problem have been documented below this line for documentation purposes.

First problem (see below) fixed, had to normalize the relative vectors that we got after crossing the vectors.
New problem found! :C

Apparently, the second problem i encountered (looking straight up) did not neccisarily have to be directly up since the vector was actually normalized to something like: "3.49925e-006 9.2714e-007 1"
Which apparently is a vector with length 1 (a quick check confirmed this).
Bit stumped at this problem.
My current try to solve it:
Code: [Select]
function relativeVector(%dir, %vec)
{
%x = getWord(%vec, 0);
%y = getWord(%vec, 1);
%z = getWord(%vec, 2);

%relYvec = vectorNormalize(%dir);
%relYx = getWord(%relYvec, 0);
if (%relYx < 0)
%relYx *= -1;
%relYy = getWord(%relYvec, 1);
if (%relYy < 0)
%relYy *= -1;

if (%relYx < 0.00001 && %relYy < 0.00001)
{
%relYvec2 = vectorNormalize(getWord(%relYvec, 0) SPC getWord(%relYvec, 1) SPC "0");
echo(%relYvec2 SPC " -len:" SPC vectorLen(%relYvec2));
%relXvec = vectorNormalize(vectorCross(%relYvec2, "0 0 1"));
%relZvec = vectorNormalize(vectorCross(%relXvec, "0 0 1"));
}
//else if (%relYvec $= "0 0 1")
//%relXvec = "1 0 0"; //Not sure if this is the best solution, but it is the most realistic one
else
{
%relXvec = vectorNormalize(vectorCross(%relYvec, "0 0 1"));
%relZvec = vectorNormalize(vectorCross(%relXvec, %relYvec));
}
%relVec = vectorAdd(vectorAdd(vectorScale(%relYvec, %y), vectorScale(%relZvec, %z)), vectorScale(%relXvec, %x));
return %relVec;
}
It did not solve it though, not at all.
Any ideas?

ORIGINAL ORIGINAL POST
First of all, let me note that i used this topic for guidance: https://forum.blockland.us/index.php?topic=286014.0
I am trying to basically do the same thing as there, track points relative from the player's eyepoint.
And while the solution given there works when looking straight forward, it seems to have some weird effect when looking up.
I found this out because i am drawing lines from point to point from specific points.
(blue lines are lines between points, red cubes are the points and the green line is the muzzleVector)
Here is it when looking forward, which is right.

And here i look more up and it seems to become more and more condensed around the z axis.

Which is not at all what i want.
Code for relative vector calculation i use right now:
Code: [Select]
function relativeVector(%dir, %vec)
{
%x = getWord(%vec, 0);
%y = getWord(%vec, 1);
%z = getWord(%vec, 2);

%relYvec = vectorNormalize(%dir);
%relXvec = vectorCross(%relYvec, "0 0 1");
%relZvec = vectorCross(%relXvec, %relYvec);
%relVec = vectorAdd(vectorAdd(vectorScale(%relYvec, %y), vectorScale(%relZvec, %z)), vectorScale(%relXvec, %x));
return %relVec;
}
Code that uses this:
Code: [Select]
function Player::calculateTrackPoint(%obj, %slot, %pointRelPos)
{
if (%pointRelPos $= "" || !isObject(%obj))
return;

%location = %obj.getMuzzlePoint(%slot);

if (%pointRelPos !$= "0 0 0")
{
%dir = %obj.getMuzzleVector(0);
%relPos = relativeVector(%dir, %pointRelPos);
%location = vectorAdd(%location, %relPos);
}

return %location;
}
This gets the muzzlepoint and adds the vector of a point relative from the muzzleVector, if that makes sense.
For a good explanation of what i want, see the topic i linked at the top.
Together with the following points put in the above function:
Code: [Select]
$AdvMel::Point[0] = "2 -1 1.5";
$AdvMel::Point[1] = "0 1.5 0";
$AdvMel::Point[2] = "-2 1 -1";
$AdvMel::Point[3] = "-2.5 -0.6 -1";
Can someone enlighten me on how i solve this problem?

For those interested, the add-on so far.
To see the points, type /togglemuzzletrack.

Other interesting things to do, but unrelated to this problem is to type "$Server::DebugMelee = 1;" into the console and swing a bit with the testSword that comes with it.
« Last Edit: June 18, 2016, 10:14:07 AM by lordician »

It would help to see the code you use.

It would help to see the code you use.
I cannot believe i forgot to add this. >_>
Hold on, fixing this unbelievable stupid mistake.

EDIT: Fixed.
So stupid of me. I kinda am sick of this problem and want to get it out of the way.
Hope to see someone who knows how i can fix this.
« Last Edit: June 05, 2016, 01:05:38 PM by lordician »

You should instead try use player.getEyePoint() and player.getEyeVector();.

You should instead try use player.getEyePoint() and player.getEyeVector();.
I am not sure how that would help, the muzzleVector and muzzlePoint do not behave oddly so changing it to the eyepoint and eyevector would have no effect.
Second of all, i want this to use the muzzle point and vector because i want them to move when the muzzlepoint moves (basically when the player does some animation like moving his hand up and down).

Bump for fix found.
I had to normalize the relative vectors i calculate by crossing the vectors...
Of course.

Though i did find some other bug that needs to be fixed, but i know what causes it.
When you look straight up, (and thus the muzzlevector runs straight through the 0 0 1 vector that we use in our calculations), the whole calculation goes weird.
I will edit the fixed code in the OP and here for anyone who needs it (in a moment).

I think this topic will leave a mark of eternal shame upon me.
EDIT:
Apparently, the second problem i encountered (looking straight up) did not neccisarily have to be directly up since the vector was actually normalized to something like: "3.49925e-006 9.2714e-007 1"
Which apparently is a vector with length 1 (a quick check confirmed this).
I am in the process of writing a fix for that.
Feel free to say how you would fix that in the relative vector function though, maybe i can make it a tiny bit more efficient or something.

EDIT2: Bit stumped at this problem.
My current try to solve it:
Code: [Select]
function relativeVector(%dir, %vec)
{
%x = getWord(%vec, 0);
%y = getWord(%vec, 1);
%z = getWord(%vec, 2);

%relYvec = vectorNormalize(%dir);
%relYx = getWord(%relYvec, 0);
if (%relYx < 0)
%relYx *= -1;
%relYy = getWord(%relYvec, 1);
if (%relYy < 0)
%relYy *= -1;

if (%relYx < 0.00001 && %relYy < 0.00001)
{
%relYvec2 = vectorNormalize(getWord(%relYvec, 0) SPC getWord(%relYvec, 1) SPC "0");
echo(%relYvec2 SPC " -len:" SPC vectorLen(%relYvec2));
%relXvec = vectorNormalize(vectorCross(%relYvec2, "0 0 1"));
%relZvec = vectorNormalize(vectorCross(%relXvec, "0 0 1"));
}
//else if (%relYvec $= "0 0 1")
//%relXvec = "1 0 0"; //Not sure if this is the best solution, but it is the most realistic one
else
{
%relXvec = vectorNormalize(vectorCross(%relYvec, "0 0 1"));
%relZvec = vectorNormalize(vectorCross(%relXvec, %relYvec));
}
%relVec = vectorAdd(vectorAdd(vectorScale(%relYvec, %y), vectorScale(%relZvec, %z)), vectorScale(%relXvec, %x));
return %relVec;
}
It did not solve it though, not at all.
Any ideas?
« Last Edit: June 07, 2016, 05:00:52 PM by lordician »

Apparently, looking as much up as you can result in you looking slightly backwards, making the whole calculation backwards a bit.
I have solved the problem now.
Here take this! It is dangerous to go alone!
Code: [Select]
function relativeVector(%dir, %vec)
{
%x = getWord(%vec, 0);
%y = getWord(%vec, 1);
%z = getWord(%vec, 2);

%relYvec = vectorNormalize(%dir);
%relYx = getWord(%relYvec, 0);
if (%relYx < 0)
%relYx *= -1;
%relYy = getWord(%relYvec, 1);
if (%relYy < 0)
%relYy *= -1;

if (%relYx < 0.00001 && %relYy < 0.00001)
{
%relYvec2 = vectorNormalize(vectorScale((getWord(%relYvec, 0) SPC getWord(%relYvec, 1) SPC "0"), -1));
%relXvec = vectorNormalize(vectorCross(%relYvec2, "0 0 1"));
%relZvec = vectorNormalize(vectorCross(%relXvec, %relYvec));
}
else
{
%relXvec = vectorNormalize(vectorCross(%relYvec, "0 0 1"));
%relZvec = vectorNormalize(vectorCross(%relXvec, %relYvec));
}
%relVec = vectorAdd(vectorAdd(vectorScale(%relYvec, %y), vectorScale(%relZvec, %z)), vectorScale(%relXvec, %x));
return %relVec;
}
While the fix is only reaaaaally relevant for this purpose and might forget things over for people who use it for different purposes, i figure the chance of people using vectors with the first two numbers being under 0.00001 is small unless they use it for player relative vectors. :)
I will take that chance.
Hopefully this helps someone else later on down the line.
Now on to the rest of the code...