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

[CS:GO][SourceMod] Pre-render grenade trails?


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
ut_tommy
Junior Member
Join Date: Aug 2010
Old 04-12-2015 , 02:40   [CS:GO][SourceMod] Pre-render grenade trails?
Reply With Quote #1

Greetings,

Can anyone experienced with SourceMod coding give me an idea of whether something like this grenade trail mod can be implemented?

I'm having a hard time working out the scope of modifications possible with SourceMod. For instance, to implement this instant grenade trail renderer I would need a method to simulate a grenades path given an initial velocity and facing. Is the physics code that governs a grenades motion accessible?

Thanks,
Tom.
ut_tommy is offline
asherkin
SourceMod Developer
Join Date: Aug 2009
Location: OnGameFrame()
Old 04-12-2015 , 05:52   Re: [CS:GO][SourceMod] Pre-render grenade trails?
Reply With Quote #2

Check the following code for drawing rocket paths to start with the drawing side, you'll need to take gravity into account (basic ballistic motion equations) and draw more lines to get the curve.
Note that I don't think CS:GO has those materials, so you'll need to find replacements (can be pulled from SM's beacon command code).

PHP Code:
#include <sourcemod>
#include <sdktools>

new g_sprite;
new 
g_glow;

public 
OnMapStart()
{
    
g_sprite PrecacheModel("materials/sprites/laser.vmt");
    
g_glow PrecacheModel("sprites/redglow1.vmt");
}

public 
OnGameFrame()
{
    for (new 
1<= MaxClientsi++)
    {
        if(
IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i))
        {
            
StartClientTrace(i);
        }
    }
}

public 
bool:StartClientTrace(client)
{
    new 
Float:vOrigin[3];
    
GetClientEyePosition(clientvOrigin);
    
    new 
Float:vAngles[3];
    
GetClientEyeAngles(clientvAngles);
    
    new 
Float:vEndPos[3];
    new 
Float:vNormal[3];
    
CreateBeam(vOriginvAnglesvEndPosvNormal);
    
    for (new 
010i++)
    {
        new 
Float:vTraceRay[3];
        
MakeVectorFromPoints(vOriginvEndPosvTraceRay);
        
        new 
Float:dotProduct GetVectorDotProduct(vNormalvTraceRay);
        
        
ScaleVector(vNormaldotProduct);
        
ScaleVector(vNormal2.0);
        
        new 
Float:vBounceVec[3];
        
SubtractVectors(vTraceRayvNormalvBounceVec);
        
        
GetVectorAngles(vBounceVecvAngles);
        
vOrigin[0] = vEndPos[0];
        
vOrigin[1] = vEndPos[1];
        
vOrigin[2] = vEndPos[2];
        
        
CreateBeam(vOriginvAnglesvEndPosvNormal);
    }
    
    return 
true;
}

public 
bool:CreateBeam(const Float:vOrigin[3], const Float:vAngles[3], Float:vEndPos[3], Float:vNormal[3])
{
    new 
Handle:trace TR_TraceRayFilterEx(vOriginvAnglesMASK_SHOTRayType_InfiniteTraceEntityFilterPlayer);
    
    if(!
TR_DidHit(trace))
    {
        
CloseHandle(trace);
        return 
false;
    }
    
    
TR_GetEndPosition(vEndPostrace);
    
TR_GetPlaneNormal(tracevNormal);
    
    
CloseHandle(trace);
    
    new 
Float:life 0.1;
    new 
Float:width 0.25;
    new 
Float:dotWidth 0.3;
    
    
TE_SetupBeamPoints(vOriginvEndPosg_sprite000lifewidth0.010.0, {25500255}, 0);
    
TE_SendToAll();
    
    
TE_SetupGlowSprite(vEndPosg_glowlifedotWidth255);
    
TE_SendToAll();
    
    return 
true;
}

bool:FireRayFromPoint(const Float:vOrigin[3], const Float:vAngles[3], Float:vEndPos[3], Float:vNormal[3])
{
    
}

public 
bool:TraceEntityFilterPlayer(entitycontentsMask)
{
    return 
entity MaxClients;

__________________
asherkin is offline
ut_tommy
Junior Member
Join Date: Aug 2010
Old 04-12-2015 , 10:24   Re: [CS:GO][SourceMod] Pre-render grenade trails?
Reply With Quote #3

Thanks asherkin.

I tried your code with the following material changes:
Code:
    g_sprite = PrecacheModel("materials/decals/paint/laser_blue_large.vmt"); 
    g_glow = PrecacheModel("materials/sprites/glow.vmt");
I can't get TE_SetupBeamPoints to render a full beam between the source and destination positions. This is what the beams look like
As you can see it stops a small distance infront of the player. The glow is rendered correctly at the end point thankfully.

Code:
void TE_SetupBeamPoints(float start[3], float end[3], int ModelIndex, int HaloIndex, int StartFrame, int FrameRate, float Life, float Width, float EndWidth, int FadeLength, float Amplitude, int Color[4], int Speed)
Code:
    new Float:life = 0.1; 
    new Float:width = 0.25; 
    new Float:dotWidth = 0.3; 
     
    TE_SetupBeamPoints(vOrigin, vEndPos, g_sprite, 0, 0, 0, life, width, 0.0, 1, 0.0, {255, 0, 0, 255}, 0);
I've tried fiddling with most of the parameters however none of the changes seem to address this issue. I haven't tried fiddling with StartFrame, FrameRate and Speed; could these be relevant to my issue?
ut_tommy is offline
ut_tommy
Junior Member
Join Date: Aug 2010
Old 04-20-2015 , 12:47   Re: [CS:GO][SourceMod] Pre-render grenade trails?
Reply With Quote #4

I managed to resolve my issue with TE_SetupBeamPoints by using a different texture, materials/sprites/laserbeam.vmt

I've got the basic ballistic motion equation in place to render a path given some value for initial grenade velocity and gravity.

Here is my updated code:

Code:
#include <sourcemod> 
#include <sdktools> 

public Plugin:myinfo =
{
    name = "Realtime Grenade Trails",
    author = "ModifiedFootage",
    description = "",
    version = "1.0",
    url = "http://www.sourcemod.net/"
};

new g_sprite; 
new Float:vGrenade = 100.0;
new Float:gravity = -1.0;
public OnMapStart() 
{ 
    g_sprite = PrecacheModel("materials/sprites/laserbeam.vmt");
} 

public OnGameFrame() 
{ 
    for (new i = 1; i <= MaxClients; i++) 
    { 
        if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i)) 
        { 
            StartClientTrace(i); 
        } 
    } 
} 

public bool:StartClientTrace(client) 
{ 
    new Float:vOrigin[3]; 
    GetClientEyePosition(client, vOrigin); 
     
    new Float:vAngles[3]; 
    GetClientEyeAngles(client, vAngles); 

    
    new Float:vForward[3]
    GetAngleVectors(vAngles, vForward, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0})
    NormalizeVector(vForward, vForward)
    ScaleVector(vForward, vGrenade)

    new Float:vPrev[3];
    new Float:vCurrent[3];
    vPrev[0] = vOrigin[0];
    vPrev[1] = vOrigin[1];
    vPrev[2] = vOrigin[2];

    new Float:vEndPos[3]; 
    new Float:vNormal[3];
    for (new i = 1; i < 10; i++) 
    { 
        vCurrent[0] = vOrigin[0] + vForward[0]*i
        vCurrent[1] = vOrigin[1] + vForward[1]*i
        vCurrent[2] = vOrigin[2] + vForward[2]*i + 0.5*gravity*i*i

        CreateBeam(vPrev, vCurrent, vEndPos, vNormal);
        
        vPrev[0] = vEndPos[0];
        vPrev[1] = vEndPos[1];
        vPrev[2] = vEndPos[2];
        

    }
     

    return true; 
} 

public bool:CreateBeam(const Float:vOrigin[3], const Float:vAngles[3], Float:vEndPos[3], Float:vNormal[3]) 
{ 
    new Handle:trace = TR_TraceRayFilterEx(vOrigin, vAngles, MASK_SHOT, RayType_EndPoint, TraceEntityFilterPlayer); 
     
    TR_GetEndPosition(vEndPos, trace); 
    TR_GetPlaneNormal(trace, vNormal); 
     
    CloseHandle(trace); 
     
    new Float:life = 0.1 
    new Float:width = 1.0; 
    new Float:dotWidth = 0.3; 

    TE_SetupBeamPoints(vOrigin, vEndPos, g_sprite, 0, 0, 0, life, width, width, 0.1, 0.0, {255, 0, 0, 255}, 0);
    TE_SendToAll(); 

    return true; 
} 

bool:FireRayFromPoint(const Float:vOrigin[3], const Float:vAngles[3], Float:vEndPos[3], Float:vNormal[3]) 
{ 
     
} 

public bool:TraceEntityFilterPlayer(entity, contentsMask) 
{ 
    return entity > MaxClients; 
}
There are two problems I could use help with at this point:
  • Grenades don't seem to spawn at eye position, how do I work out where one would spawn?
  • What constants should I use for gravity and initial grenade velocities?

I'll go and get the collision/bounce code working that was provided above and post back with the result.

Thanks!

UPDATE:

I've got basic bounce mechanics working, and now another variable to tune, the coefficient of restitution.

Code:
#include <sourcemod> 
#include <sdktools> 

public Plugin:myinfo =
{
    name = "Realtime Grenade Trails",
    author = "ModifiedFootage",
    description = "",
    version = "1.0",
    url = "http://www.sourcemod.net/"
};

new g_sprite;
ConVar vGrenade;
ConVar gravity;
ConVar cor; // coefficient of restituation
ConVar life;
ConVar fade;
new Float:stationaryVelocityMagnitude = 0.1;
new Float:maxStationaryCount = 3;

public void OnPluginStart()
{
    vGrenade = CreateConVar("rgt_vGrenade","100.0", "Initial grenade velocity");
    gravity = CreateConVar("rgt_gravity","-1.5", "Grenade gravity acceleration constant");
    cor = CreateConVar("rgt_cor","0.8", "Grenade coefficient of restituation constant");
    life = CreateConVar("rgt_life","0.1", "Trail render duration");
    fade = CreateConVar("rgt_fade","0.1", "Trail render duration");
}
public OnMapStart() 
{ 
    g_sprite = PrecacheModel("materials/sprites/laserbeam.vmt");
} 

public OnGameFrame() 
{ 
    for (new i = 1; i <= MaxClients; i++) 
    { 
        if(IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i)) 
        { 
            StartClientTrace(i); 
        } 
    } 
} 

public bool:StartClientTrace(client) 
{ 
    new Float:vOrigin[3]; 
    GetClientEyePosition(client, vOrigin); 
     
    new Float:vAngles[3]; 
    GetClientEyeAngles(client, vAngles); 

    
    new Float:vForward[3]
    GetAngleVectors(vAngles, vForward, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0})
    NormalizeVector(vForward, vForward)
    ScaleVector(vForward, GetConVarFloat(vGrenade))

    new Float:vPrev[3];
    new Float:vCurrent[3];
    vPrev[0] = vOrigin[0];
    vPrev[1] = vOrigin[1];
    vPrev[2] = vOrigin[2];

    new Float:vEndPos[3]; 
    new Float:vNormal[3];
    new bool:didHit;
    new Float:t = 0.0;
    new Float:dt = 1.0;
    new steps = 0;
    new maxSteps = 2000;
    new stationaryCount = 0;
    while (steps <= maxSteps)
    { 
        t += dt;
        steps++;
        vCurrent[0] = vOrigin[0] + vForward[0]*t
        vCurrent[1] = vOrigin[1] + vForward[1]*t
        vCurrent[2] = vOrigin[2] + vForward[2]*t + 0.5*GetConVarFloat(gravity)*t*t

        didHit = CreateBeam(vPrev, vCurrent, vEndPos, vNormal, didHit);
        // Bounce if hit!
        
        if (didHit) {
            // When did we hit?
            new Float:hitTime = t;

            // At what velocity/direction?
            new Float:hitVelocity[3];
            hitVelocity[0] = vForward[0]
            hitVelocity[1] = vForward[1]
            hitVelocity[2] = vForward[2] + GetConVarFloat(gravity)*hitTime;

            // Reflection vector
            // r = d - 2(d.n)n // r = d - e
            new Float:reflectionVector[3];
            new Float:d[3];
            new Float:e[3];
            d[0] = hitVelocity[0];
            d[1] = hitVelocity[1];
            d[2] = hitVelocity[2];
            e[0] = vNormal[0];
            e[1] = vNormal[1];
            e[2] = vNormal[2];
            ScaleVector(e,2*GetVectorDotProduct(d,vNormal));
            SubtractVectors(d,e,reflectionVector);
            
            // start new trajectory
            t = 0
            vOrigin[0] = vEndPos[0];
            vOrigin[1] = vEndPos[1];
            vOrigin[2] = vEndPos[2];

            vForward[0] = reflectionVector[0];
            vForward[1] = reflectionVector[1];
            vForward[2] = reflectionVector[2];
            
            // apply coefficient of restituation
            ScaleVector(vForward, GetConVarFloat(cor));
            
        }
        new Float:vMoved[3];
        MakeVectorFromPoints(vPrev, vEndPos, vMoved);
        if (GetVectorLength(vMoved) <= stationaryVelocityMagnitude) {
            stationaryCount++;
            if (stationaryCount > maxStationaryCount) {
                break;
            }
        } else {
            stationaryCount = 0;
        }
        
        vPrev[0] = vEndPos[0];
        vPrev[1] = vEndPos[1];
        vPrev[2] = vEndPos[2];
        
        
    }
    return true; 
} 

public bool:CreateBeam(const Float:vOrigin[3], const Float:vDestination[3], Float:vEndPos[3], Float:vNormal[3], bool:didHit) 
{ 
    new Handle:trace = TR_TraceRayFilterEx(vOrigin, vDestination, MASK_SHOT, RayType_EndPoint, TraceEntityFilterPlayer); 
     
    TR_GetEndPosition(vEndPos, trace); 
    TR_GetPlaneNormal(trace, vNormal); 
    didHit = TR_DidHit(trace)
    
    CloseHandle(trace); 
     
    new Float:width = 0.3;
     
    TE_SetupBeamPoints(vOrigin, vEndPos, g_sprite, 0, 0, 0, GetConVarFloat(life), width, width, GetConVarFloat(fade), 0.0, {255, 0, 0, 255}, 0);
    TE_SendToAll(); 

    return true; 
} 

public bool:TraceEntityFilterPlayer(entity, contentsMask) 
{ 
    return entity > MaxClients; 
}

Last edited by ut_tommy; 04-20-2015 at 22:05. Reason: Cleaned up code before I submitted, but didn't check if it compiled. Fixed.
ut_tommy 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 22:21.


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