Raised This Month: $51 Target: $400
 12% 

About normals, tracerays and accuracy


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Dr. Greg House
Professional Troll,
Part-Time Asshole
Join Date: Jun 2010
Old 07-25-2014 , 18:34   About normals, tracerays and accuracy
Reply With Quote #1

Basically I'm trying to get the normal of a tracerays hit surface.
GetPlaneNormal() is bugged however, or at least can be considered unreliable (I talked to asherkin about this and he has similar issues).
So I thought I could go ahead and place two tracerays next to each other, and get the angle from the hitpoints.
Have a snippet:

Code:
#pragma semicolon 1

#include <sourcemod>
#include <sdkhooks>
#include <sdktools>

public Plugin:myinfo = 
{
    name = "New Plugin",
    author = "PP(R)TH: Dr. Gregory House",
    description = "<- Description ->",
    version = "1.0",
    url = "<- URL ->"
}

public OnPluginStart()
{
    RegConsoleCmd("sm_getnormal", GetNormalCommand_Used);
}

public Action:GetNormalCommand_Used(client, args)
{
    decl Float:pos[3];
    decl Float:currentAngle[3];
    decl Float:firstHit[3];
    decl Float:secondHit[3];
    
    GetClientAbsOrigin(client, pos);
    pos[2] += 100.0;
    
    GetClientEyeAngles(client, currentAngle);
    
    new Handle:trace = TR_TraceRayFilterEx(pos, Float:{-89.0, 0.0, 0.0}, MASK_ALL, RayType_Infinite, TraceEntityFilter);
    
    if(TR_DidHit(trace))
    {
        TR_GetEndPosition(firstHit, trace);
        
        CloseHandle(trace);
        
        decl Float:offset[3];
        GetAngleVectors(currentAngle, offset, NULL_VECTOR, NULL_VECTOR);
        
        ScaleVector(offset, 15.0);
        
        AddVectors(offset, pos, offset);
        
        trace = TR_TraceRayFilterEx(offset, Float:{-89.0, 0.0, 0.0}, MASK_ALL, RayType_Infinite, TraceEntityFilter);
        
        if(TR_DidHit(trace))
        {
            TR_GetEndPosition(secondHit, trace);
            
            CloseHandle(trace);
            
            MakeVectorFromPoints(secondHit, firstHit, offset);
            
            PrintToChatAllVector("Pos:", pos);
            PrintToChatAllVector("FirstHit:", firstHit);
            PrintToChatAllVector("Second pos:", offset);
            PrintToChatAllVector("SecondHit:", secondHit);
            
            decl Float:angles[3];
            GetVectorAngles(offset, angles);
            
            PrintToChatAllVector("Angles: ", angles);
            return Plugin_Handled;
        }
        else
        {
            CloseHandle(trace);
            
            PrintToChatAll("No hit");
            
            return Plugin_Handled;
        }
    }
    else
    {
        CloseHandle(trace);
        
        PrintToChatAll("No hit");
        
        return Plugin_Handled;
    }
}

public bool:TraceEntityFilter(entity, contentsMask)
{
    return entity == 0;
}

PrintToChatAllVector(String:prefix[] = "", Float:vector[3])
{
    PrintToChatAll("%s X: %f, Y: %f, Z: %f", prefix, vector[0], vector[1], vector[2]);
}
This doesn't work either, exact same issue/values as with GetPlaneNormal. You can try out yourself, bind this to a command and run around (You can use the tilted planes in koth_nucleus for example).
I don't know if I missed anything (I hope I'm humiliating myself here actually) but this doesn't even work reliably on flat ground.

Things I've tried:

-Using -89.0 instead of 90.0 as a Hail Mary wtf
-Different distances between the tracerays
__________________
Santa or Satan?

Watch out when you're paying people for private requests! Most stuff already exists and you can hardly assess the quality of what you'll get, and if it's worth the money.

Last edited by Dr. Greg House; 07-25-2014 at 23:25.
Dr. Greg House is offline
friagram
Veteran Member
Join Date: Sep 2012
Location: Silicon Valley
Old 07-25-2014 , 21:05   Re: About normals, tracerays and accuracy
Reply With Quote #2

This always works fine for me, i have a lot of prop placing plugins that use it.
I think some months ago valve changed the x angles, so you have to fix their bounds on the normal to get it to be consistent.

Aside from that, one side of the grid will have the forward facing down, and the other up. It makes sense from a math point of view, but not logically.
__________________
Profile - Plugins
Add me on steam if you are seeking sp/map/model commissions.
friagram is offline
Dr. Greg House
Professional Troll,
Part-Time Asshole
Join Date: Jun 2010
Old 07-25-2014 , 21:11   Re: About normals, tracerays and accuracy
Reply With Quote #3

The problem for me is that it doesn't make sense from a two-point-trace-ray kind of view.
Also I have the same values/issues for both methods.
__________________
Santa or Satan?

Watch out when you're paying people for private requests! Most stuff already exists and you can hardly assess the quality of what you'll get, and if it's worth the money.
Dr. Greg House is offline
friagram
Veteran Member
Join Date: Sep 2012
Location: Silicon Valley
Old 07-25-2014 , 22:12   Re: About normals, tracerays and accuracy
Reply With Quote #4

It always gives you a vector that is perpendicular to the plane.... It's most commonly used in light shaders, or in modeling (manipulating it changes the direction at which light hits the surface).
All you are getting is a direction here, so you can't assume local rotation along that vector (pretty sure it is undefined, or static).

http://en.m.wikipedia.org/wiki/Surface_normal
__________________
Profile - Plugins
Add me on steam if you are seeking sp/map/model commissions.
friagram is offline
Dr. Greg House
Professional Troll,
Part-Time Asshole
Join Date: Jun 2010
Old 07-25-2014 , 23:04   Re: About normals, tracerays and accuracy
Reply With Quote #5

Friagram, I know what a normal is...
The issue at hand is that GetPlaneNormal doesn't (always) give correct values (in my test cases I always had the z-component to be -1 even though I was standing on an evenly tilted plane).
The same goes for the two traceray method. If there's a tilted plane which changes from one hitpoint to another in 10 pixel in height, I expect the hitpoints to be 10 pixels apart in z-difference.
You can check out the snippet for yourself if you want to.

EDIT: I think I should clarify.
Basically I don't directly want the normal, but the pitch of the plane. So the two traceray method is will just directly return the plane's angles, while the normal method will need some more magic. Point is that it turns out that the issue already lies in getting the correct values for these two methods.
__________________
Santa or Satan?

Watch out when you're paying people for private requests! Most stuff already exists and you can hardly assess the quality of what you'll get, and if it's worth the money.

Last edited by Dr. Greg House; 07-25-2014 at 23:56.
Dr. Greg House is offline
friagram
Veteran Member
Join Date: Sep 2012
Location: Silicon Valley
Old 07-26-2014 , 04:55   Re: About normals, tracerays and accuracy
Reply With Quote #6

I mostly use this for aligning geometry (models to other models, or models to world), and it's never been a problem. The normal has always returned properly for me, but keep in mind that it uses physics data.

Are you sure that the data you are looking for is even there? Because, lighting and all of that super costly crap that uses high-volume raycasts is calculated when the map is compiled on the triangle level, but then it's compressed down and stored as lightmaps. Everything gets compressed and optimized, so it would not surprise me if displacement physics, complex convex shapes, etc all get averaged/optimized physics hulls. It's not like source engine has some super precise physics to start with, IIRC IK is disabled in multiplayer, and even on flat planes, characters often float on the ground/stairs. There may be some way to test the individual triangles and get their normal, but that would have stupid-high overhead, so I wouldn't be surprised if there's not. Only renderers (clients) need that type stuff, and it's only used for calculating light bounces, shadows, phong, etc... and it's all thrown at the GPUs (which is designed to handle that stuff).
__________________
Profile - Plugins
Add me on steam if you are seeking sp/map/model commissions.
friagram is offline
Dr. Greg House
Professional Troll,
Part-Time Asshole
Join Date: Jun 2010
Old 07-26-2014 , 05:43   Re: About normals, tracerays and accuracy
Reply With Quote #7

Well, I can't speak for the normal part, however I'd expect the two-traceray-method to work fine. But it doesn't.

If you go in front of the ramps in koth_nucleus by manual calculations using getpos I get a slope of 14° (keep in mind those ramps start with a small step and I didnt even go half up, and I can't guarantee that I was parallel to the slope), by observation I can tell you that it is somewhere around 24°).

I'd love to discuss this more further and show more stuff.
Irc?
__________________
Santa or Satan?

Watch out when you're paying people for private requests! Most stuff already exists and you can hardly assess the quality of what you'll get, and if it's worth the money.

Last edited by Dr. Greg House; 07-26-2014 at 05:49.
Dr. Greg House is offline
friagram
Veteran Member
Join Date: Sep 2012
Location: Silicon Valley
Old 07-26-2014 , 06:25   Re: About normals, tracerays and accuracy
Reply With Quote #8

Eww irc. I got steam
Check your mask, and make sure you are ignoring player clips. Lots of stairs and ramps will be heavily playerclipped which allows for smooth player movement up /down inclines. It's physics data, but a mask_shot or something of the like will penetrate it.
__________________
Profile - Plugins
Add me on steam if you are seeking sp/map/model commissions.
friagram is offline
Dr. Greg House
Professional Troll,
Part-Time Asshole
Join Date: Jun 2010
Old 07-26-2014 , 06:42   Re: About normals, tracerays and accuracy
Reply With Quote #9

Okay, MASK_SHOT works fine.
It still flips between lower and upper bound angles (20° and 340°, idk if this was the correct phrasing), but as long as this is working, I'm fine.
Thanks.

BTW: Why "Eww"?

EDIT: Actually I'm going to have to take this back.

Current code:
Code:
public Action:GetNormalCommand_Used(client, args)
{
    decl Float:pos[3];
    decl Float:currentAngle[3];
    decl Float:firstHit[3];
    decl Float:secondHit[3];
    
    GetClientAbsOrigin(client, pos);
    pos[2] += 100.0;
    
    GetClientEyeAngles(client, currentAngle);
    decl Float:offset[3];
    GetAngleVectors(currentAngle, offset, NULL_VECTOR, NULL_VECTOR);
    
    ScaleVector(offset, 30.0);
    
    PrintToChatAllVector("Offset:", offset);
    PrintToChatAllVector("Pos:", pos);
    
    new Handle:trace = TR_TraceRayFilterEx(pos, Float:{-89.0, 0.0, 0.0}, MASK_SHOT, RayType_Infinite, TraceEntityFilter, client);
    
    if(TR_DidHit(trace))
    {
        TR_GetEndPosition(firstHit, trace);
        
        CloseHandle(trace);
        
        AddVectors(pos, offset, pos);
        
        trace = TR_TraceRayFilterEx(pos, Float:{-89.0, 0.0, 0.0}, MASK_SHOT, RayType_Infinite, TraceEntityFilter, client);
        
        if(TR_DidHit(trace))
        {
            TR_GetEndPosition(secondHit, trace);
            
            CloseHandle(trace);
            
            MakeVectorFromPoints(secondHit, firstHit, offset);
            
            PrintToChatAllVector("FirstHit:", firstHit);
            PrintToChatAllVector("Second pos:", pos);
            PrintToChatAllVector("SecondHit:", secondHit);
            
            decl Float:angles[3];
            GetVectorAngles(offset, angles);
            
            PrintToChatAllVector("Angles: ", angles);
            
            return Plugin_Handled;
        }
        else
        {
            CloseHandle(trace);
            
            PrintToChatAll("No hit");
            
            return Plugin_Handled;
        }
    }
    else
    {
        CloseHandle(trace);
        
        PrintToChatAll("No hit");
        
        return Plugin_Handled;
    }
}

public bool:TraceEntityFilter(entity, contentsMask, any:client)
{
    return entity != client;
}
Two screenshots:
http://i.imgur.com/G3W2csc.jpg
http://i.imgur.com/xnVj8X0.jpg

Last edited by Dr. Greg House; 07-26-2014 at 07:35.
Dr. Greg House is offline
friagram
Veteran Member
Join Date: Sep 2012
Location: Silicon Valley
Old 07-26-2014 , 16:40   Re: About normals, tracerays and accuracy
Reply With Quote #10

Not exactly sure why you are not using getplanenormal, and also, the trace will always hit something with that filter.. Eventually because world and sealed. I'm not all familiar with this method, so I don't see why you are using 89 degrees instead of 90. Also, why add 100 to pos instead of using getclienteyeposition, not that it really matters. You'll have to excuse the fact that it's been some 10+ years now since I'v taken linear algebra classes, and I only use what little maths now I need to get by. Shit, the farthest I could probably get at something simple like integrating would be to draw the integral symbol at this point.

I'm going to assume that there is some inaccuracy in this method vs the other. A lot of model stuff will often store normals for each triangle explicitly, rather than calculate them on the fly (like via smoothing groups). I'd assume physics data has them indexed for quick lookup, but I'm likely to be totally wrong here.
__________________
Profile - Plugins
Add me on steam if you are seeking sp/map/model commissions.

Last edited by friagram; 07-26-2014 at 16:42.
friagram is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 03:05.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode