Beispiel #1
0
// Returns true if the segment e1-e2 intersects the shape boundary 
// segment s1-s2, blocking visibility.
//
bool segmentShapeIntersect(const Point& e1, const Point& e2, const Point& s1,
        const Point& s2, bool& seenIntersectionAtEndpoint)
{
    if (segmentIntersect(e1, e2, s1, s2))
    {
        // Basic intersection of segments.
        return true;
    }
    else if ( (((s2 == e1) || pointOnLine(s1, s2, e1)) && 
               (vecDir(s1, s2, e2) != 0)) 
              ||
              (((s2 == e2) || pointOnLine(s1, s2, e2)) &&
               (vecDir(s1, s2, e1) != 0)) )
    {
        // Segments intersect at the endpoint of one of the segments.  We
        // allow this once, but the second one blocks visibility.  Otherwise
        // shapes butted up against each other could have visibility through
        // shapes.
        if (seenIntersectionAtEndpoint)
        {
            return true;
        }
        seenIntersectionAtEndpoint = true;
    }
    return false;
}
Beispiel #2
0
// Returns true if the segment cd intersects the segment ab, blocking
// visibility.
//
// Based on the code of 'IntersectProp' and 'Intersect'.
//
bool segmentIntersect(const Point& a, const Point& b, const Point& c,
        const Point& d)
{
    int ab_c = vecDir(a, b, c);
    if (ab_c == 0)
    {
        return false;
    }

    int ab_d = vecDir(a, b, d);
    if (ab_d == 0)
    {
        return false;
    }

    // It's ok for either of the points a or b to be on the line cd,
    // so we don't have to check the other two cases.

    int cd_a = vecDir(c, d, a);
    int cd_b = vecDir(c, d, b);

    // Is an intersection if a and b are on opposite sides of cd,
    // and c and d are on opposite sides of the line ab.
    //
    // Note: this is safe even though the textbook warns about it
    // since, unlike them, our vecDir is equivilent to 'AreaSign'
    // rather than 'Area2'.
    return (((ab_c * ab_d) < 0) && ((cd_a * cd_b) < 0));
}
Beispiel #3
0
// Gives the side of a corner that a point lies on:
//      1   anticlockwise
//     -1   clockwise
// e.g.                     /|s2
//       /s3          -1   / |
//      /                 /  |
//  1  |s2  -1           / 1 |  -1
//     |                /    |
//     |s1           s3/     |s1
//     
int cornerSide(const Point &c1, const Point &c2, const Point &c3,
        const Point& p)
{
    int s123 = vecDir(c1, c2, c3);
    int s12p = vecDir(c1, c2, p);
    int s23p = vecDir(c2, c3, p);

    if (s123 == 1)
    {
        if ((s12p >= 0) && (s23p >= 0))
        {
            return 1;
        }
        return -1;
    }
    else if (s123 == -1)
    {
        if ((s12p <= 0) && (s23p <= 0))
        {
            return -1;
        }
        return 1;
    }

    // c1-c2-c3 are collinear, so just return vecDir from c1-c2
    return s12p;
}
Beispiel #4
0
// Returns true iff the point p in a valid region that can contain
// shortest paths.  a0, a1, a2 are ordered vertices of a shape.
//
// Based on the code of 'InCone'.
//
bool inValidRegion(bool IgnoreRegions, const Point& a0, const Point& a1,
        const Point& a2, const Point& b)
{
    // r is a0--a1
    // s is a1--a2

    int rSide = vecDir(b, a0, a1);
    int sSide = vecDir(b, a1, a2);

    bool rOutOn = (rSide <= 0);
    bool sOutOn = (sSide <= 0);

    bool rOut = (rSide < 0);
    bool sOut = (sSide < 0);

    if (vecDir(a0, a1, a2) > 0)
    {
        // Convex at a1:
        //
        //   !rO      rO
        //    sO      sO
        //
        // ---s---+
        //        |
        //   !rO  r   rO
        //   !sO  |  !sO
        //
        //
        if (IgnoreRegions)
        {
            return (rOutOn && !sOut) || (!rOut && sOutOn);
        }
        return (rOutOn || sOutOn);
    }
    else
    {
        // Concave at a1:
        //
        //   !rO      rO
        //   !sO     !sO
        //
        //        +---s---
        //        |
        //   !rO  r   rO
        //    sO  |   sO
        //
        //
        return (IgnoreRegions ? false : (rOutOn && sOutOn));
    }
}
Beispiel #5
0
Polygon Polygon::simplify(void) const
{
    Polygon simplified = *this;
    std::vector<Point>::iterator it = simplified.ps.begin();
    if (it != simplified.ps.end()) ++it;

    // Combine collinear line segments into single segments:
    for (size_t j = 2; j < simplified.size(); )
    {
        if (vecDir(simplified.ps[j - 2], simplified.ps[j - 1], 
                simplified.ps[j]) == 0)
        {
            // These three points make up two collinear segments, so just
            // compine them into a single segment.
            it = simplified.ps.erase(it);
        }
        else
        {
            ++j;
            ++it;
        }
    }

    return simplified;
}
Beispiel #6
0
// DeadTakeDamage - takedamage function called when a monster's corpse is damaged.
int CBaseMonster::DeadTakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType)
{
	// grab the vector of the incoming attack. ( pretend that the inflictor is a little lower than it really is, so the body will tend to fly upward a bit).
	Vector vecDir(0, 0, 0);

	if (!FNullEnt(pevInflictor))
	{
		CBaseEntity *pInflictor = CBaseEntity::Instance(pevInflictor);
		if (pInflictor)
		{
			vecDir = (pInflictor->Center() - Vector(0, 0, 10) - Center()).Normalize();
			vecDir = g_vecAttackDir = vecDir.Normalize();
		}
	}

// turn this back on when the bounding box issues are resolved.
#if 0

	pev->flags &= ~FL_ONGROUND;
	pev->origin.z += 1;

	// let the damage scoot the corpse around a bit.
	if (!FNullEnt(pevInflictor) && (pevAttacker->solid != SOLID_TRIGGER))
	{
		pev->velocity = pev->velocity + vecDir * -DamageForce(flDamage);
	}

#endif

	// kill the corpse if enough damage was done to destroy the corpse and the damage is of a type that is allowed to destroy the corpse.
	if (bitsDamageType & DMG_GIB_CORPSE)
	{
		if (pev->health <= flDamage)
		{
			pev->health = -50;
			Killed(pevAttacker, GIB_ALWAYS);
			return 0;
		}

		// Accumulate corpse gibbing damage, so you can gib with multiple hits
		pev->health -= flDamage * 0.1;
	}

	return 1;
}
void LudoRenderer::SetLight(const LudoVector * const position, int r, int g, int b)
{
    D3DLIGHT9 light;
    ZeroMemory(&light, sizeof(D3DLIGHT9));

    light.Type = D3DLIGHT_DIRECTIONAL;
    light.Diffuse.a = 1.0f;
    light.Diffuse.r = (float)r / 255.0f;
    light.Diffuse.g = (float)g / 255.0f;
    light.Diffuse.b = (float)b / 255.0f;
    light.Range = 4000.0f;

    D3DXVECTOR3 vecDir(position->GetX(), position->GetY(), position->GetZ());
    D3DXVec3Normalize( (D3DXVECTOR3 *)&light.Direction, &vecDir);

    //m_d3DDev->SetLight(0, &light);
    //m_d3DDev->LightEnable(0, TRUE);
}
Beispiel #8
0
// Returns true iff the point c lies on the closed segment ab.
// To be used when the points are known to be collinear.
//
// Based on the code of 'Between'.
//
bool inBetween(const Point& a, const Point& b, const Point& c)
{
    // We only call this when we know the points are collinear,
    // otherwise we should be checking this here.
    COLA_ASSERT(vecDir(a, b, c, 0.0001) == 0);

    if ((fabs(a.x - b.x) > 1) && (a.x != b.x))
    {
        // not vertical
        return (((a.x < c.x) && (c.x < b.x)) ||
                ((b.x < c.x) && (c.x < a.x)));
    }
    else
    {
        return (((a.y < c.y) && (c.y < b.y)) ||
                ((b.y < c.y) && (c.y < a.y)));
    }
}
Beispiel #9
0
void CAWP::PrimaryAttack()
{
	if( m_iClip <= 0 )
		return;

	m_iClip--;

	m_pPlayer->SetAnimation( PLAYER_ATTACK1 );

	Vector vecSrc( m_pPlayer->GetGunPosition() );
	Vector vecAim( m_pPlayer->GetAutoaimVector( AUTOAIM_2DEGREES ) );
	Vector vecAcc( g_vecZero );

	if ( !( m_pPlayer->pev->flags & FL_ONGROUND ) )
		vecAcc = vec3_t( 0.85, 0.85, 0.85 );
	else if ( m_pPlayer->pev->velocity.Length2D() > 140 || !scope )
		vecAcc = vec3_t( 0.25, 0.25, 0.25 );
    else if ( m_pPlayer->pev->velocity.Length2D() > 10 )
		vecAcc = vec3_t( 0.10, 0.10, 0.10 );
    else
		vecAcc = vec3_t( 0, 0, 0 );

	Vector vecDir( m_pPlayer->FireBulletsPlayer( 1, vecSrc, vecAim, vecAcc, 8192,0, 0, 114, m_pPlayer->pev, m_pPlayer->random_seed ) );

	SendWeaponAnim( AWP_SHOOT1 );

	PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_event, 0.0,
		(float *)&g_vecZero, (float *)&g_vecZero,
		vecDir.x, vecDir.y, 0, 0, (m_iClip ? 0 : 1), 0 );

	m_pPlayer->pev->fov = 0;
	m_pPlayer->m_iFOV = m_pPlayer->pev->fov;
	scope = false;
	g_engfuncs.pfnSetClientMaxspeed(m_pPlayer->edict(), 210 );
#ifndef CLIENT_DLL
	MESSAGE_BEGIN( MSG_ONE, gmsgScopeToggle, NULL, m_pPlayer->pev );
		WRITE_BYTE( 0 );
	MESSAGE_END();
#endif

	m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 1.45;
	m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.45;
	m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.45;
}
Beispiel #10
0
TEST(collideWorld, ray2sphere)
{
	Vector3 p1(0.0f, 0.0f, 0.0f);
	Vector3 p2(0.0f, 4.0f, 0.0f);
	Vector3 vecDir(0.0f, 2.0f, 0.0f);
	float r = 2.0f;
	Sphere sphere(p2, r);
	Ray ray(p1, vecDir);
	CollidableObject object1(&ray, p1, 0);
	CollidableObject object2(&sphere, p1, 1);
/*
	CollisionWorld world;
	world.addObject(object1);
	world.addObject(object2);
	world.computeCollision();

	printf("# of objects: %d\n", world.getObjectSize());
	printf("# of collides: %d\n", world.getCollideSize());
	*/
}
Beispiel #11
0
// Returns true iff the point c lies on the closed segment ab.
//
bool pointOnLine(const Point& a, const Point& b, const Point& c, 
        const double tolerance)
{
    // Do this a bit more optimally for orthogonal AB line segments.
    if (a.x == b.x)
    {
        return (a.x == c.x) &&
                (((a.y < c.y) && (c.y < b.y)) ||
                 ((b.y < c.y) && (c.y < a.y)));
    }
    else if (a.y == b.y)
    {
        return (a.y == c.y) &&
                (((a.x < c.x) && (c.x < b.x)) ||
                 ((b.x < c.x) && (c.x < a.x)));
    }

    // Or use the general case.
    return (vecDir(a, b, c, tolerance) == 0) && inBetween(a, b, c);
}
Beispiel #12
0
void Rocket_Update(Object *pObject)
{
	Projectile *pProjectile=(Projectile *)pObject;

	Matrix mat;
	Matrix *pLast;

	Object_GetMatrix(pObject,&mat);
	mat.SetColumn(3, mat.GetColumn(3) + pProjectile->vecVel);

	Object_GetMatrixPtrLast(pObject,&pLast);

	Vec3 vecDir(mat.GetColumn(0)*0.25f);

	Trail_AddPoint((Object*)pProjectile->pTrails[0], pLast->GetColumn(3), vecDir);

	vecDir = (mat.GetColumn(1)*0.25f);
	Trail_AddPoint((Object*)pProjectile->pTrails[1], pLast->GetColumn(3), vecDir);

	if(Level_TestLineCollide( pLast->GetColumn(3), mat.GetColumn(3) ))
	{
		pProjectile->fLife = -1.f;

		ColData Data;

		// Get the collision data
		Collision_GetColData(&Data);

		vecDir = (mat.GetColumn(0)*0.25f);

		Trail_AddPoint((Object*)pProjectile->pTrails[0], Data.vecPoint, vecDir);

		vecDir = (mat.GetColumn(1)*0.25f);
		Trail_AddPoint((Object*)pProjectile->pTrails[1], Data.vecPoint, vecDir);

		// NIK: Create particle effect at collision position
		Particles_Create( 0, Data.vecPoint );
	}

	Object_SetMatrix(pObject, &mat);
}
Beispiel #13
0
// Returns true iff the three points are colinear.
//
bool colinear(const Point& a, const Point& b, const Point& c,
        const double tolerance)
{

    // Do this a bit more optimally for orthogonal AB line segments.
    if (a == b)
    {
        return true;
    }
    else if (a.x == b.x)
    {
        return (a.x == c.x);
    }
    else if (a.y == b.y)
    {
        return (a.y == c.y);
    }

    // Or use the general case.
    return (vecDir(a, b, c, tolerance) == 0);
    
}
Beispiel #14
0
// Returns true iff the point q is inside (or on the edge of) the
// polygon argpoly.
//
// This is a fast version that only works for convex shapes.  The
// other version (inPolyGen) is more general.
//
bool inPoly(const Polygon& poly, const Point& q, bool countBorder)
{
    size_t n = poly.size();
    const std::vector<Point>& P = poly.ps;
    bool onBorder = false;
    for (size_t i = 0; i < n; i++)
    {
        // point index; i1 = i-1 mod n
        size_t prev = (i + n - 1) % n;
        int dir = vecDir(P[prev], P[i], q);
        if (dir == -1)
        {
            // Point is outside
            return false;
        }
        // Record if point was on a boundary.
        onBorder |= (dir == 0);
    }
    if (!countBorder && onBorder)
    {
        return false;
    }
    return true;
}
Beispiel #15
0
ShaderDevise* ShaderDevise::init(int w, int h, HWND hWnd) {
	ShaderDevise& sd(ShaderDevise::inst());

	if(!(sd._d3d = Direct3DCreate9(D3D_SDK_VERSION))) return 0;

	D3DPRESENT_PARAMETERS d3dpp = {w, h, D3DFMT_UNKNOWN, 0, D3DMULTISAMPLE_NONE, 0,
	D3DSWAPEFFECT_DISCARD,NULL,TRUE,TRUE,D3DFMT_D24S8,0,0}; 

	if( FAILED(sd._d3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &sd._device))) {
		if( FAILED(sd._d3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &sd._device))) {
			if( FAILED(sd._d3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &sd._device))) {
				if( FAILED(sd._d3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &sd._device))) {
					sd._d3d->Release();
					sd._d3d = NULL;
					sd._device = NULL;
					return 0;
				}
			}
		}
	}

	sd._device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
	sd._device->SetRenderState(D3DRS_LIGHTING, TRUE);
	sd._device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
	sd._device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	sd._device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
	sd._device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	sd._device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);  
 	sd._device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
	sd._device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
	sd._device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
	sd._device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);

	ZeroMemory(&sd.light, sizeof(D3DLIGHT9)*8);
	sd.light[0].Type			= D3DLIGHT_DIRECTIONAL;
	sd.light[0].Diffuse.r = 0.5f;
	sd.light[0].Diffuse.g = 0.5f;
	sd.light[0].Diffuse.b = 0.5f;
	sd.light[0].Diffuse.a = 1.0f;
	sd.light[0].Specular.r	= sd.light[0].Specular.g = sd.light[0].Specular.b = sd.light[0].Specular.a = 1.0f;
	sd.light[0].Ambient.r = 0.098f;
	sd.light[0].Ambient.g = 0.098f;
	sd.light[0].Ambient.b = 0.439f;
	sd.light[0].Ambient.a = 1.0f;
	
	D3DXVECTOR3 vecDir(-0.76f, -0.52f, -0.31f);
	D3DXVec3Normalize((D3DXVECTOR3*)&sd.light[0].Direction, &vecDir);
	sd._device->SetLight(0, &sd.light[0]);
	sd._device->LightEnable(0, TRUE);
	sd.light_vec[0] = sd.light[0].Direction;
	sd._device->SetRenderState(D3DRS_SPECULARENABLE, true);

	D3DMATERIAL9 mat = {
		1, 1, 1, 1,
		1.0f, 1.0f, 1.0f, 1.0f,
		0.8f, 0.8f, 0.8f, 1.0f,
		0, 0, 0, 0,
		5
	};

	sd._device->SetMaterial(&mat);

	// フォントの生成
	int fontsize = 24;
	D3DXFONT_DESC lf = {fontsize, 0, 0, 1, 0, SHIFTJIS_CHARSET, OUT_TT_ONLY_PRECIS,
	PROOF_QUALITY, FIXED_PITCH | FF_MODERN, "MS ゴシック"};
	if(FAILED(D3DXCreateFontIndirect(sd._device, &lf, &sd.font))){
		return 0;
	}

	return &sd;
}
Beispiel #16
0
// The damage is coming from inflictor, but get mad at attacker
// This should be the only function that ever reduces health.
// bitsDamageType indicates the type of damage sustained, ie: DMG_SHOCK
//
// Time-based damage: only occurs while the monster is within the trigger_hurt.
// When a monster is poisoned via an arrow etc it takes all the poison damage at once.
int CBaseMonster::__MAKE_VHOOK(TakeDamage)(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType)
{
	if (pev->takedamage == DAMAGE_NO)
		return 0;

	if (!IsAlive())
	{
		return DeadTakeDamage(pevInflictor, pevAttacker, flDamage, bitsDamageType);
	}

	if (pev->deadflag == DEAD_NO)
	{
		// no pain sound during death animation.
		PainSound();
	}

	// LATER: make armor consideration here!
	float flTake = flDamage;

	// set damage type sustained
	m_bitsDamageType |= bitsDamageType;

	// grab the vector of the incoming attack. ( pretend that the inflictor is a little lower than it really is, so the body will tend to fly upward a bit).
	Vector vecDir(0, 0, 0);

	if (!FNullEnt(pevInflictor))
	{
		CBaseEntity *pInflictor = CBaseEntity::Instance(pevInflictor);

		if (pInflictor)
		{
#ifndef PLAY_GAMEDLL
			vecDir = (pInflictor->Center() - Vector(0, 0, 10) - Center()).Normalize();
#else
			// TODO: fix test demo
			vecDir = NormalizeSubtract<
				float_precision, float, float_precision, float_precision
				>(Center(), pInflictor->Center() - Vector(0, 0, 10));
#endif
			vecDir = g_vecAttackDir = vecDir.Normalize();
		}
	}

	// add to the damage total for clients, which will be sent as a single
	// message at the end of the frame
	// TODO: remove after combining shotgun blasts?
	if (IsPlayer())
	{
		if (pevInflictor)
		{
			pev->dmg_inflictor = ENT(pevInflictor);
		}

		pev->dmg_take += flTake;
	}

	pev->health -= flTake;

	if (m_MonsterState == MONSTERSTATE_SCRIPT)
	{
		SetConditions(bits_COND_LIGHT_DAMAGE);
		return 0;
	}

	if (pev->health <= 0.0f)
	{
		g_pevLastInflictor = pevInflictor;

		if (bitsDamageType & DMG_ALWAYSGIB)
			Killed(pevAttacker, GIB_ALWAYS);

		else if (bitsDamageType & DMG_NEVERGIB)
			Killed(pevAttacker, GIB_NEVER);
		else
			Killed(pevAttacker, GIB_NORMAL);

		g_pevLastInflictor = NULL;
		return 0;
	}
	if ((pev->flags & FL_MONSTER) && !FNullEnt(pevAttacker))
	{
		if (pevAttacker->flags & (FL_MONSTER | FL_CLIENT))
		{
			if (pevInflictor)
			{
				if (m_hEnemy == NULL || pevInflictor == m_hEnemy->pev || !HasConditions(bits_COND_SEE_ENEMY))
					m_vecEnemyLKP = pevInflictor->origin;
			}
			else
			{
				m_vecEnemyLKP = pev->origin + (g_vecAttackDir * 64);
			}

			MakeIdealYaw(m_vecEnemyLKP);

			if (flDamage > 20.0f)
			{
				SetConditions(bits_COND_LIGHT_DAMAGE);
			}

			if (flDamage >= 20.0f)
			{
				SetConditions(bits_COND_HEAVY_DAMAGE);
			}
		}
	}

	return 1;
}
Beispiel #17
0
// Returns true iff the point c lies on the closed segment ab.
//
bool pointOnLine(const Point& a, const Point& b, const Point& c, 
        const double tolerance)
{
    return (vecDir(a, b, c, tolerance) == 0) && inBetween(a, b, c);
}