📄 gravpath.cpp
字号:
pathlength = 0;
from = NULL;
to = NULL;
nextnode = 1;
gravPathManager.RemovePath(this);
}
void GravPath::Clear
(
void
)
{
nextnode = 1;
pathlength = 0;
from = NULL;
to = NULL;
pathlist.FreeObjectList();
}
void GravPath::Reset
(
void
)
{
nextnode = 1;
}
GravPathNode *GravPath::Start
(
void
)
{
return from;
}
GravPathNode *GravPath::End
(
void
)
{
return to;
}
void GravPath::AddNode
(
GravPathNode *node
)
{
int num;
Vector r,addp;
if ( !from )
{
from = node;
}
to = node;
pathlist.AddObject( GravPathNodePtr( node ) );
num = NumNodes();
if ( num > 1 )
{
pathlength += ( node->worldorigin - GetNode( num )->worldorigin ).length();
}
r.setXYZ(node->Radius(),node->Radius(),node->Radius());
addp = node->worldorigin + r;
AddPointToBounds(addp.vec3(),mins.vec3(),maxs.vec3());
addp = node->worldorigin - r;
AddPointToBounds(addp.vec3(),mins.vec3(),maxs.vec3());
}
GravPathNode *GravPath::GetNode
(
int num
)
{
return pathlist.ObjectAt( num );
}
GravPathNode *GravPath::NextNode
(
void
)
{
if ( nextnode <= NumNodes() )
{
return pathlist.ObjectAt( nextnode++ );
}
return NULL;
}
Vector GravPath::ClosestPointOnPath
(
Vector pos,
Entity &ent,
float *ret_dist,
float *speed,
float *radius
)
{
GravPathNode *s;
GravPathNode *e;
int num;
int i;
float bestdist;
Vector bestpoint;
float dist;
float segmentlength;
Vector delta;
Vector p1;
Vector p2;
Vector p3;
float t;
trace_t trace;
num = NumNodes();
s = GetNode( 1 );
trace = G_Trace( pos, ent.mins, ent.maxs, s->worldorigin, &ent, MASK_PLAYERSOLID, "GravPath::ClosestPointOnPath 1" );
bestpoint = s->worldorigin;
delta = bestpoint - pos;
bestdist = delta.length();
*speed = s->Speed();
*radius = s->Radius();
for( i = 2; i <= num; i++ )
{
e = GetNode( i );
// check if we're closest to the endpoint
delta = e->worldorigin - pos;
dist = delta.length();
if ( dist < bestdist )
{
trace = G_Trace( pos, ent.mins, ent.maxs, e->worldorigin, &ent, MASK_PLAYERSOLID, "GravPath::ClosestPointOnPath 2" );
bestdist = dist;
bestpoint = e->worldorigin;
*speed = e->Speed();
*radius = e->Radius();
}
// check if we're closest to the segment
p1 = e->worldorigin - s->worldorigin;
segmentlength = p1.length();
p1 *= 1 / segmentlength;
p2 = pos - s->worldorigin;
t = p1 * p2;
if ( ( t > 0 ) && ( t < segmentlength ) )
{
p3 = ( p1 * t ) + s->worldorigin;
delta = p3 - pos;
dist = delta.length();
if ( dist < bestdist )
{
trace = G_Trace( pos, ent.mins, ent.maxs, p3, &ent, MASK_PLAYERSOLID, "GravPath::ClosestPointOnPath 3" );
bestdist = dist;
bestpoint = p3;
*speed = (e->Speed() * t) + (s->Speed() * (1.0f - t));
*radius = (e->Radius() * t) + (s->Radius() * (1.0f - t));
}
}
s = e;
}
*ret_dist = bestdist;
return bestpoint;
}
float GravPath::DistanceAlongPath
(
Vector pos,
float *speed
)
{
GravPathNode *s;
GravPathNode *e;
int num;
int i;
float bestdist;
float dist;
float segmentlength;
Vector delta;
Vector segment;
Vector p1;
Vector p2;
Vector p3;
float t;
float pathdist;
float bestdistalongpath;
float oosl;
pathdist = 0;
num = NumNodes();
s = GetNode( 1 );
delta = s->worldorigin - pos;
bestdist = delta.length();
bestdistalongpath = 0;
*speed = s->Speed();
for( i = 2; i <= num; i++ )
{
e = GetNode( i );
segment = e->worldorigin - s->worldorigin;
segmentlength = segment.length();
// check if we're closest to the endpoint
delta = e->worldorigin - pos;
dist = delta.length();
if ( dist < bestdist )
{
bestdist = dist;
bestdistalongpath = pathdist + segmentlength;
*speed = e->Speed();
}
// check if we're closest to the segment
oosl = ( 1 / segmentlength );
p1 = segment * oosl;
p1.normalize();
p2 = pos - s->worldorigin;
t = p1 * p2;
if ( ( t > 0 ) && ( t < segmentlength ) )
{
p3 = ( p1 * t ) + s->worldorigin;
delta = p3 - pos;
dist = delta.length();
if ( dist < bestdist )
{
bestdist = dist;
bestdistalongpath = pathdist + t;
t *= oosl;
*speed = (e->Speed() * t) + (s->Speed() * (1.0f - t));
}
}
s = e;
pathdist += segmentlength;
}
return bestdistalongpath;
}
Vector GravPath::PointAtDistance
(
float dist
)
{
GravPathNode *s;
GravPathNode *e;
int num;
int i;
Vector delta;
Vector p1;
float t;
float pathdist;
float segmentlength;
num = NumNodes();
s = GetNode( 1 );
pathdist = 0;
for( i = 2; i <= num; i++ )
{
e = GetNode( i );
delta = e->worldorigin - s->worldorigin;
segmentlength = delta.length();
if ( ( pathdist + segmentlength ) > dist )
{
t = dist - pathdist;
p1 = delta * ( t / segmentlength );
return p1 + s->worldorigin;
}
s = e;
pathdist += segmentlength;
}
// cap it off at start or end of path
return s->worldorigin;
}
void GravPath::DrawPath
(
Event *ev
)
{
Vector s;
Vector e;
Vector offset;
GravPathNode *node;
int num;
int i;
float r = ev->GetFloat(1);
float g = ev->GetFloat(2);
float b = ev->GetFloat(3);
Event *event;
num = NumNodes();
node = GetNode( 1 );
s = node->worldorigin;
offset = Vector( r, g, b ) * 4 + Vector( 0, 0, 0 );
offset = Vector(0, 0, 0);
for( i = 2; i <= num; i++ )
{
node = GetNode( i );
e = node->worldorigin;
G_DebugLine( s + offset, e + offset, r, g, b, 1 );
s = e;
}
G_DebugBBox(origin,mins-origin,maxs-origin,1,0,0,1);
event = new Event(EV_DrawGravPath);
event->AddFloat(r);
event->AddFloat(g);
event->AddFloat(b);
PostEvent(event,0.1f);
}
int GravPath::NumNodes
(
void
)
{
return pathlist.NumObjects();
}
float GravPath::Length
(
void
)
{
return pathlength;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -