Junior Member
|
04-20-2015
, 12:47
Re: [CS:GO][SourceMod] Pre-render grenade trails?
|
#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.
|
|