Example #1
0
bool Intersects(pcs_polygon &polygon, vector3d plane_point, vector3d plane_normal)
{
	if (polygon.verts.size() < 3)
		return false; // um.. this is a line not a polygon

	bool infront = InFrontofPlane(polygon.verts[0].point, plane_point, plane_normal);

	for (unsigned int i = 1; i < polygon.verts.size(); i++)
	{
		if (DistanceToPlane(polygon.verts[i].point, plane_point, plane_normal) != 0 && // if it's on the plane we don't care
			infront != InFrontofPlane(polygon.verts[i].point, plane_point, plane_normal))
			return true;
	}

	return false;
}
Example #2
0
float DistanceToPolygon(const vec3& p, tvector<vec3>& v, vec3 n)
{
	float flPlaneDistance = DistanceToPlane(p, v[0], n);

	size_t i;

	bool bFoundPoint = false;

	for (i = 0; i < v.size()-2; i++)
	{
		if (PointInTriangle(p, v[0], v[i+1], v[i+2]))
		{
			bFoundPoint = true;
			break;
		}
	}

	if (bFoundPoint)
		return flPlaneDistance;

	float flClosestPoint = -1;
	for (i = 0; i < v.size(); i++)
	{
		float flPointDistance = (v[i] - p).Length();
		if (flClosestPoint == -1 || (flPointDistance < flClosestPoint))
			flClosestPoint = flPointDistance;

		float flLineDistance;
		if (i == v.size() - 1)
			flLineDistance = DistanceToLineSegment(p, v[i], v[0]);
		else
			flLineDistance = DistanceToLineSegment(p, v[i], v[i+1]);

		if (flClosestPoint == -1 || (flLineDistance < flClosestPoint))
			flClosestPoint = flLineDistance;
	}

	return flClosestPoint;
}
Example #3
0
bool InFrontofPlane(vector3d point, vector3d plane_point, vector3d plane_normal)
{
	return DistanceToPlane(point, plane_point, plane_normal) >= 0;
}
Example #4
0
void SplitPolygon(std::vector<pcs_polygon> &polygons, int polynum, vector3d plane_point, vector3d plane_normal, std::vector<pcs_polygon> &newpolys)
{
	std::vector<pcs_polygon> splitpolys(2); // 0 = front vert, 1 = back vert
	std::vector<int> pairs;
	std::vector<pcs_vertex> points;
	pairs.resize(polygons[polynum].verts.size() * 2);
	pcs_vertex temp;
	unsigned int i, j = 0;
	float uvdelta;

	for (i = 0; i < polygons[polynum].verts.size() * 2; i += 2)
	{
		pairs[i] = j % polygons[polynum].verts.size();
		pairs[i+1] = (j+1) % polygons[polynum].verts.size();
		j++;
	}

	float dtempa, dtempb;
	// compile the new list of points
	for (i = 0; i < pairs.size(); i += 2)
	{
		dtempa = DistanceToPlane(polygons[polynum].verts[pairs[i]].point, plane_point, plane_normal);
		dtempb = DistanceToPlane(polygons[polynum].verts[pairs[i+1]].point, plane_point, plane_normal);
		if ((dtempa <= 0.0001 && dtempa >= -0.0001) || (dtempb <= 0.0001 && dtempb >= -0.0001))
		// one of these points lays on the plane... add them both without modification
		{

			AddIfNotInList(points, polygons[polynum].verts[pairs[i]]);
			AddIfNotInList(points, polygons[polynum].verts[pairs[i+1]]);
		}
		else // neither of them was not on the plane.. are they on the same side?
		{

			if (InFrontofPlane(polygons[polynum].verts[pairs[i]].point, plane_point, plane_normal) == 
				InFrontofPlane(polygons[polynum].verts[pairs[i+1]].point, plane_point, plane_normal))
			// both on same side - add them
			{
				AddIfNotInList(points, polygons[polynum].verts[pairs[i]]);
				AddIfNotInList(points, polygons[polynum].verts[pairs[i+1]]);
			}
			else
			// different sides - cut and add
			{
				uvdelta = FindIntersection(temp.point, polygons[polynum].verts[pairs[i]].point, 
						polygons[polynum].verts[pairs[i+1]].point, plane_point, plane_normal);
				temp.norm = polygons[polynum].norm;
				temp.u = uvdelta * (polygons[polynum].verts[pairs[i]].u - polygons[polynum].verts[pairs[i+1]].u);
				temp.v = uvdelta * (polygons[polynum].verts[pairs[i]].v - polygons[polynum].verts[pairs[i+1]].v);

				AddIfNotInList(points, polygons[polynum].verts[pairs[i]]);
				AddIfNotInList(points, temp);
				AddIfNotInList(points, polygons[polynum].verts[pairs[i+1]]);
			}
		}
	}


	// split the polygons with the list we have

	int in = 0;
	for (i = 0; i < points.size(); i++)
	{
		dtempa = DistanceToPlane(points[i].point, plane_point, plane_normal) ;
		if (dtempa <= 0.0001 && dtempa >= -0.0001)
		// there WILL be two points in the list this is true for
		{
			AddIfNotInList(splitpolys[0].verts, points[i]);
			AddIfNotInList(splitpolys[1].verts, points[i]);
			
			if (in == 0)
				in = 1;
			else
				in = 0;
		}
		else
		{
			AddIfNotInList(splitpolys[in].verts, points[i]);
		}
	}

	// triangle our new polylist
	TriangulateMesh(splitpolys);

	// replace our current poly with polygon zero - add the others
	polygons[polynum] = splitpolys[0];
	in = newpolys.size();
	newpolys.resize(in+splitpolys.size());
	for (i = 1; i < splitpolys.size(); i++)
	{
		newpolys[in+i] = splitpolys[i];
	}
}
Example #5
0
// --------------------------------------------------------------------
//                      add_track_mark
// --------------------------------------------------------------------
void add_track_mark (CControl *ctrl, int *id) {
    TVector3 width_vector;
    TVector3 left_vector;
    TVector3 right_vector;
    double magnitude;
    track_quad_t *q, *qprev, *qprevprev;
    TVector3 vel;
    double speed;
    TVector3 left_wing, right_wing;
    double left_y, right_y;
    double dist_from_surface;
    TPlane surf_plane;
    double comp_depth;
    double tex_end;
    double dist_from_last_mark;
    TVector3 vector_from_last_mark;
	TTerrType *TerrList = Course.TerrList;

    if (param.perf_level < 3) return;

    q = &track_marks.quads[track_marks.current_mark%MAX_TRACK_MARKS];
    qprev = &track_marks.quads[(track_marks.current_mark-1)%MAX_TRACK_MARKS];
    qprevprev = &track_marks.quads[(track_marks.current_mark-2)%MAX_TRACK_MARKS];

    vector_from_last_mark = SubtractVectors (ctrl->cpos, track_marks.last_mark_pos);
    dist_from_last_mark = NormVector (&vector_from_last_mark);
	
	*id = Course.GetTerrainIdx (ctrl->cpos.x, ctrl->cpos.z, 0.5);
	if (*id < 1) {
		break_track_marks();
		return;
	} 

	if (TerrList[*id].trackmarks < 1) {
		break_track_marks();
		return;
	} 
    
	vel = ctrl->cvel;
    speed = NormVector (&vel);
    if (speed < SPEED_TO_START_TRENCH) {
		break_track_marks();
		return;
    }

    width_vector = CrossProduct (ctrl->cdirection, MakeVector (0, 1, 0));
    magnitude = NormVector (&width_vector);
    if  (magnitude == 0) {
		break_track_marks();
		return;
    }

    left_vector = ScaleVector (TRACK_WIDTH/2.0, width_vector);
    right_vector = ScaleVector (-TRACK_WIDTH/2.0, width_vector);
    left_wing =  SubtractVectors (ctrl->cpos, left_vector);
    right_wing = SubtractVectors (ctrl->cpos, right_vector);
    left_y = Course.FindYCoord (left_wing.x, left_wing.z);
    right_y = Course.FindYCoord (right_wing.x, right_wing.z);
    
	if (fabs(left_y-right_y) > MAX_TRACK_DEPTH) {
		break_track_marks();
		return;
    }

    surf_plane = Course.GetLocalCoursePlane (ctrl->cpos);
    dist_from_surface = DistanceToPlane (surf_plane, ctrl->cpos);
	// comp_depth = get_compression_depth(Snow);
	comp_depth = 0.1;
    if  (dist_from_surface >= (2 * comp_depth)) {
		break_track_marks();
		return;
    }

    if (!continuing_track) {
		break_track_marks();
		q->track_type = TRACK_HEAD;
		q->v1 = MakeVector (left_wing.x, left_y + TRACK_HEIGHT, left_wing.z);
		q->v2 = MakeVector (right_wing.x, right_y + TRACK_HEIGHT, right_wing.z);
		q->n1 = Course.FindCourseNormal (q->v1.x, q->v1.z);
		q->n2 = Course.FindCourseNormal (q->v2.x, q->v2.z);
		q->t1 = MakeVector2(0.0, 0.0);
		q->t2 = MakeVector2(1.0, 0.0);
		track_marks.next_mark = track_marks.current_mark + 1;
    } else {
		if  (track_marks.next_mark == track_marks.current_mark) {
		    q->v1 = qprev->v3;
	    	q->v2 = qprev->v4;
		    q->n1 = qprev->n3;
		    q->n2 = qprev->n4;
		    q->t1 = qprev->t3; 
		    q->t2 = qprev->t4;
	    	if (qprev->track_type != TRACK_HEAD) qprev->track_type = TRACK_MARK;
	    	q->track_type = TRACK_MARK;
		}
		q->v3 = MakeVector (left_wing.x, left_y + TRACK_HEIGHT, left_wing.z);
		q->v4 = MakeVector (right_wing.x, right_y + TRACK_HEIGHT, right_wing.z);
		q->n3 = Course.FindCourseNormal (q->v3.x, q->v3.z);
		q->n4 = Course.FindCourseNormal (q->v4.x, q->v4.z);
		tex_end = speed*g_game.time_step/TRACK_WIDTH;
		if (q->track_type == TRACK_HEAD) {
		    q->t3= MakeVector2 (0.0, 1.0);
		    q->t4= MakeVector2 (1.0, 1.0);
		} else {
		    q->t3 = MakeVector2 (0.0, q->t1.y + tex_end);
		    q->t4 = MakeVector2 (1.0, q->t2.y + tex_end);
		}
		track_marks.current_mark++;
		track_marks.next_mark = track_marks.current_mark;
    }
    q->alpha = min ((2*comp_depth-dist_from_surface)/(4*comp_depth), 1.0);
    track_marks.last_mark_time = g_game.time;
    continuing_track = true;
}
Example #6
0
void CLaser::OnSetOwner(CBaseEntity* pOwner)
{
	BaseClass::OnSetOwner(pOwner);

	CDigitank* pTank = dynamic_cast<CDigitank*>(pOwner);
	if (!pTank)
		return;

	SetGlobalAngles(VectorAngles((pTank->GetLastAim() - GetGlobalOrigin()).Normalized()));
	SetGlobalOrigin(pOwner->GetGlobalOrigin());
	SetGlobalVelocity(Vector(0,0,0));
	SetGlobalGravity(Vector(0,0,0));

	m_flTimeExploded = GameServer()->GetGameTime();

	Vector vecForward, vecRight;
	AngleVectors(GetGlobalAngles(), &vecForward, &vecRight, NULL);

	for (size_t i = 0; i < GameServer()->GetMaxEntities(); i++)
	{
		CBaseEntity* pEntity = CBaseEntity::GetEntity(i);
		if (!pEntity)
			continue;

		if (!pEntity->TakesDamage())
			continue;

		if (pEntity->GetOwner() == pOwner->GetOwner())
			continue;

		float flDistance = DistanceToPlane(pEntity->GetGlobalOrigin(), GetGlobalOrigin(), vecRight);
		if (flDistance > 4 + pEntity->GetBoundingRadius())
			continue;

		// Cull objects behind
		if (vecForward.Dot(pEntity->GetGlobalOrigin() - GetGlobalOrigin()) < 0)
			continue;

		if (pEntity->Distance(GetGlobalOrigin()) > LaserLength())
			continue;

		pEntity->TakeDamage(pOwner, this, DAMAGE_LASER, m_flDamage, flDistance < pEntity->GetBoundingRadius()-2);

		CDigitank* pTank = dynamic_cast<CDigitank*>(pEntity);
		if (pTank)
		{
			float flRockIntensity = 0.5f;
			Vector vecDirection = (pTank->GetGlobalOrigin() - pOwner->GetGlobalOrigin()).Normalized();
			pTank->RockTheBoat(flRockIntensity, vecDirection);
		}
	}

	CDigitanksPlayer* pCurrentTeam = DigitanksGame()->GetCurrentLocalDigitanksPlayer();

	if (pCurrentTeam && pCurrentTeam->GetVisibilityAtPoint(GetGlobalOrigin()) < 0.1f)
	{
		if (pCurrentTeam->GetVisibilityAtPoint(GetGlobalOrigin() + AngleVector(GetGlobalAngles())*LaserLength()) < 0.1f)
		{
			// If the start and end points are both in the fog of war, delete it now that we've aready done the damage so it doesn't get rendered later.
			if (GameNetwork()->IsHost())
				Delete();
		}
	}
}
// --------------------------------------------------------------------
//                      add_track_mark
// --------------------------------------------------------------------
void add_track_mark(const CControl *ctrl, int *id) {
    if (param.perf_level < 3)
		return;

	TTerrType *TerrList = &Course.TerrList[0];

	*id = Course.GetTerrainIdx (ctrl->cpos.x, ctrl->cpos.z, 0.5);
	if (*id < 1) {
		break_track_marks();
		return;
	}

	if (!TerrList[*id].trackmarks) {
		break_track_marks();
		return;
	}

	TVector3 vel = ctrl->cvel;
    double speed = NormVector (vel);
    if (speed < SPEED_TO_START_TRENCH) {
		break_track_marks();
		return;
    }

    TVector3 width_vector = CrossProduct (ctrl->cdirection, TVector3 (0, 1, 0));
    double magnitude = NormVector (width_vector);
    if (magnitude == 0) {
		break_track_marks();
		return;
    }

    TVector3 left_vector = ScaleVector (TRACK_WIDTH/2.0, width_vector);
    TVector3 right_vector = ScaleVector (-TRACK_WIDTH/2.0, width_vector);
    TVector3 left_wing =  SubtractVectors (ctrl->cpos, left_vector);
    TVector3 right_wing = SubtractVectors (ctrl->cpos, right_vector);
    double left_y = Course.FindYCoord (left_wing.x, left_wing.z);
    double right_y = Course.FindYCoord (right_wing.x, right_wing.z);

	if (fabs(left_y-right_y) > MAX_TRACK_DEPTH) {
		break_track_marks();
		return;
    }

    TPlane surf_plane = Course.GetLocalCoursePlane (ctrl->cpos);
    double dist_from_surface = DistanceToPlane (surf_plane, ctrl->cpos);
	// comp_depth = get_compression_depth(Snow);
	double comp_depth = 0.1;
    if (dist_from_surface >= (2 * comp_depth)) {
		break_track_marks();
		return;
    }

	if(track_marks.quads.size() < MAX_TRACK_MARKS)
		track_marks.quads.push_back(track_quad_t());
	list<track_quad_t>::iterator qprev = track_marks.current_mark;
	if(track_marks.current_mark == track_marks.quads.end())
		track_marks.current_mark = track_marks.quads.begin();
	else
		track_marks.current_mark = incrementRingIterator(track_marks.current_mark);
	list<track_quad_t>::iterator q = track_marks.current_mark;

    if (!continuing_track) {
		q->track_type = TRACK_HEAD;
		q->v1 = TVector3 (left_wing.x, left_y + TRACK_HEIGHT, left_wing.z);
		q->v2 = TVector3 (right_wing.x, right_y + TRACK_HEIGHT, right_wing.z);
		q->v3 = TVector3 (left_wing.x, left_y + TRACK_HEIGHT, left_wing.z);
		q->v4 = TVector3 (right_wing.x, right_y + TRACK_HEIGHT, right_wing.z);
		q->n1 = Course.FindCourseNormal (q->v1.x, q->v1.z);
		q->n2 = Course.FindCourseNormal (q->v2.x, q->v2.z);
		q->t1 = TVector2(0.0, 0.0);
		q->t2 = TVector2(1.0, 0.0);
    } else {
		q->track_type = TRACK_TAIL;
		if (qprev != track_marks.quads.end()) {
		    q->v1 = qprev->v3;
	    	q->v2 = qprev->v4;
		    q->n1 = qprev->n3;
		    q->n2 = qprev->n4;
		    q->t1 = qprev->t3;
		    q->t2 = qprev->t4;
	if (qprev->track_type == TRACK_TAIL) qprev->track_type = TRACK_MARK;
		}
		q->v3 = TVector3 (left_wing.x, left_y + TRACK_HEIGHT, left_wing.z);
		q->v4 = TVector3 (right_wing.x, right_y + TRACK_HEIGHT, right_wing.z);
		q->n3 = Course.FindCourseNormal (q->v3.x, q->v3.z);
		q->n4 = Course.FindCourseNormal (q->v4.x, q->v4.z);
		double tex_end = speed*g_game.time_step/TRACK_WIDTH;
		if (q->track_type == TRACK_HEAD) {
		    q->t3= TVector2 (0.0, 1.0);
		    q->t4= TVector2 (1.0, 1.0);
		} else {
		    q->t3 = TVector2 (0.0, q->t1.y + tex_end);
		    q->t4 = TVector2 (1.0, q->t2.y + tex_end);
		}
    }
    q->alpha = min ((2*comp_depth-dist_from_surface)/(4*comp_depth), 1.0);
    continuing_track = true;
}
const bool Plane::PointOnPlane(Vector3d & point) {
    double d = 0;
    return DistanceToPlane(point) == d;
}