PDA

View Full Version : Get angle of wall



DjTranceFire
25th October 2016, 09:36
Hey there :)
I'm currently trying to recreate my portal mod. Everything is working fine so far, but i have a small problem.
I'm trying to spawn my portal model at a wall or at the floor/ceiling and thats working, but its not the right angle.
I need a small function that gets the angle of whatever you are looking at (wall, floor, ceiling) but i absolutly dont know how.
I think that should be possible if i try to get 3 points of what i'm looking at but thats all i have for now.
Does there any function exist that someone has created in the past that i could use or anything else that i could use to get started?

Sorry for my bad english, i hope its not to hard to understand.

voron00
25th October 2016, 10:35
trace = bulletTrace(model.origin, model.origin + (somexdir, someydir, somezdir), false, model);
model.origin = trace["position"];
model.angles = vectorNormalize(trace["normal"])

Could be something like this or at least that is the direction you have to look for. The trace["normal"] is the thing you are looking for but not sure if it can be applied to models, this needs some testing but im 1 lazy ass...:D
Edit: Also take a look at kung's portal mod https://killtube.org/showthread.php?1593-DOWNLOAD-CoD2-Portal-Mod proably has what you need.

IzNoGoD
25th October 2016, 12:15
Just put that trace["normal"] into your playfx function, or use vectortoangles() on it and set your model.angles to that.

Might have to offset that a bit (90 degrees maybe)

kung foo man
26th October 2016, 05:27
Uploaded my old portal mod: https://github.com/kungfooman/cod2_portal/

Video:


https://www.youtube.com/watch?v=FEHuttG9jMs&feature=youtu.be

https://github.com/kungfooman/cod2_portal/blob/master/mod/portal.gsc#L47


bluePortal.angles = utils\math::orientToNormal(newPos["normal"]+(0.01,0.01,0.01));


Can't really remember why I added the 0.01, probably because wall vectors are mostly like 0,0,1 or 0,1,0 etc. and orientToNormal() didn't work with zero values.

Edit: Server is testable here: /connect root.killtube.org:29900

Server will run till root is restarted (aka screen session killed).

DjTranceFire
26th October 2016, 10:59
bluePortal.angles = utils\math::orientToNormal(newPos["normal"]+(0.01,0.01,0.01));



I already tested that but for some reason its rotating my model into all directions.
https://www.youtube.com/watch?v=hhnywxTmrlY

The models at the spawn wall are in their normal direction if you spawn them with the radiant, just for comparison.

kung foo man
27th October 2016, 01:39
Would be useful if you post video with debug printbolds of normal + calculated angle.

And show your exact code with your orientToNormal function.

And try what IzNoGoD said: portal.angles = vectorToAngles(trace["normal"]);

And add more surfaces to your map, which aren't all straight walls. Lots of different slopes to test all kinds of trace normals (or just test in a stock map, should have more variety in surfaces).

Ni3ls
27th October 2016, 09:28
Which COD is that in your video Trance?

DjTranceFire
27th October 2016, 11:34
Would be useful if you post video with debug printbolds of normal + calculated angle.

And show your exact code with your orientToNormal function.

And try what IzNoGoD said: portal.angles = vectorToAngles(trace["normal"]);

And add more surfaces to your map, which aren't all straight walls. Lots of different slopes to test all kinds of trace normals (or just test in a stock map, should have more variety in surfaces).

The code behind the portal is this:



function watchAttack()
{
player = self;
orangePortal = util::spawn_model("portal_orange", (0,0,-1000000), 0);

i = 1;

while(isDefined(player))
{
if(player AttackButtonPressed() && !player ThrowButtonPressed())
{
newPos = player _utils::lookAt(orangePortal);

if(!isDefined(newPos))
{
WAIT_SERVER_FRAME;
continue;
}

orangePortal.origin = newPos["position"];
orangePortal.angles = VectortoAngles(newPos["normal"]) + (0,90,0);
orangePortal.lookupNormal = newPos["normal"];
orangePortal MoveZ(2,0.1);

player IPrintLn(" ");
player IPrintLn(" ");
player IPrintLn(" ");
player IPrintLn(i + ". GetPlayerAngles: " + player GetPlayerAngles());
player IPrintLn(i + ". Normal: " + newPos["normal"]);
player IPrintLn(i + ". orientToNormal: " + _utils::orientToNormal(newPos["normal"]+(0.01,0.01,0.01)));
player IPrintLn(i + ". VectorToAngles: " + VectortoAngles(newPos["normal"]));
i += 1;

if(!isDefined(player.orangePortal))
player.orangePortal = orangePortal;

while (self AttackButtonPressed())
WAIT_SERVER_FRAME;
}

WAIT_SERVER_FRAME;
}

orangePortal Delete();
}



orientToNormal:



function orientToNormal(normal)
{
horNormal = (normal[0], normal[1], 0);
horLength = Length(horNormal);

if(!horLength)
return(0,0,0);

horDir = VectorNormalize(horNormal);
negHeight = normal[2] + -1;
tangent = (horDir[0] * negHeight, horDir[1] * negHeight, horLength);
plantAngle = VectortoAngles(tangent);

return plantAngle;
}



lookAt:



function lookAt(toIgnore)
{
player = self;

originStart = player GetEye() + (0,0,25);
angles = player GetPlayerAngles();
forward = AnglesToForward(angles);

originEnd = originStart + VectorScale(forward, 1000000);

trace = BulletTrace(originStart, originEnd, false, toIgnore);

if (trace["fraction"] == 1)
return undefined;

return trace;
}



Its basically the same as in your portal mod. Its the stuff you have send me while i was trying to create the mod for cod4 years ago.
The only difference i have found is that vectorScale is a build in function now, but i tested it with your vectorScale function too, no differences.

I added more walls to my testmap so that there are more different angles to test on, i also added a few prints. If you need any other prints, let me know.

New Video:
https://www.youtube.com/watch?v=SunWQUnDbyU

In the video i'm using


orangePortal.angles = VectortoAngles(newPos["normal"]) + (0,90,0);

For now its the closest i can get to what i want.
As you can see, its perfect for walls in any angle, but as soon as it gets to the ground or some kind of a ramp, its not working anymore.
And for some reason the portal is sometimes stuck inside of the walls (starting at 9sec. in the video).



Which COD is that in your video Trance?
Its Black Ops 3.

kung foo man
27th October 2016, 21:53
function orientToNormal(normal)
{
horNormal = (normal[0], normal[1], 0);
horLength = Length(horNormal);

if(!horLength)
return(0,0,0);

horDir = VectorNormalize(horNormal);
negHeight = normal[2] + -1; // <<<<<<<<<<<<<<<<<<<
tangent = (horDir[0] * negHeight, horDir[1] * negHeight, horLength);
plantAngle = VectortoAngles(tangent);

return plantAngle;
}


yiz m8 thats not how negation works: * -1 instead

IzNoGoD
27th October 2016, 21:55
Just vectorscale by -1.

DjTranceFire
27th October 2016, 22:21
Now i'm confused. What do i have to do? :D
I obv changed that + to *. I dont know how that happened :D

//edit:
After taking a look at my video again i realized something thats weird.
On the third ramp (0.35) the print from


VectortoAngles(newPos["normal"])

is (330,0,0)
If i set the angles of the object directly to that value its the same as in the video and as you can see its wrong.
If i set it to (0,0,330), its exactly as it should be.
Why the hell is that shit basically mirrored? Is there something that i'm missing there?

kung foo man
27th October 2016, 23:14
Maybe BO3 has another coordinate system. Just try to flip the values in script, e.g.:




tmp= utils\math::orientToNormal(newPos["normal"]+(0.01,0.01,0.01));
tmp = (tmp[2], tmp[1], tmp[0]);
bluePortal.angles = tmp;

DjTranceFire
28th October 2016, 12:09
https://www.youtube.com/watch?v=jRcodiPLwfs


So with:


newangles = VectortoAngles(newPos["normal"]) + (0,90,0);
orangePortal.angles = (newangles[2],newangles[1],newangles[0]);

Its working as it should. Its flat to the walls and flat to the floor and ramps.
Still weird that somehow x,y,z changed.
With orientToNormal the portal is still rotated into all directions. The values doesnt seem to be correct is you can see in the prints.

Now there are 2 problems left until the portal placement is done.

1. Sometimes the portals are stuck inside of the wall. (Video at: 0.04)
2. For some reason its sometimes not taking the direction that it should. (Video at: 0.25)
You can see that when i place the portal on the ground, its 90° rotated.
Obv. thats only the case if i look in that direction, if i turn myself 90° the Portal is correct.
So it seems like its not using the direction the player is looking at.

IzNoGoD
28th October 2016, 14:40
This should fix your in-wall stuff:


placeportal(portalmodel)
{
trace = bullettrace(self geteyepos(), self geteyepos() + vectorscale(anglestoforward(self getplayerangles()), 1000), false, undefined);
if(trace["fraction"] < 1)
{
//actually place portal here
portalmodel.origin = trace["origin"] + vectorscale(trace["normal"], 0.01); //put it outside the wall
portalmodel.angles = vectortoangles(trace["normal"]);
return true;
}
return false;
}

DjTranceFire
30th October 2016, 06:10
Everything is working fine now, the only problem thats left, is the rotation of the model while placed on the floor/ceiling.
Is there any chance to rotate the model on the floor with the player angle? (video at 0.25)

IzNoGoD
30th October 2016, 08:12
Just check if normal[2] == 1 || normal[2] == -1

Then use portal.angles = (0, player getplayerangles()[2], 0);