Пример #1
0
//-----------------------------------------------------------------------
bool gkObjectManager::checkSelected( uint8 type, f32 size, bool draging )
{
	// first of all, get the 3 axis end point at screenspace [8/25/2011 Kaiming-Desktop]
	Vec2 vCursor = GetIEditor()->getMainViewport()->getCursorOnClientScreen();
	Vec3 vAxis3D;
	Vec3 vCenter3D;

	Vec3 vCenterReal = ms_pCurrentPick->getWorldPosition();
	Vec3 vDirReal(0,0,0);

	vCenter3D = gEnv->pRenderer->ProjectScreenPos( vCenterReal );

	switch(type)
	{
	case GKSTUDIO_AXIS_X:
		vDirReal = ms_pCurrentPick->getOrientation().GetColumn0();
		break;
	case GKSTUDIO_AXIS_Y:
		vDirReal = ms_pCurrentPick->getOrientation().GetColumn1();
		break;
	case GKSTUDIO_AXIS_Z:
		vDirReal = ms_pCurrentPick->getOrientation().GetColumn2();
		break;
	}

	vAxis3D = gEnv->pRenderer->ProjectScreenPos( ms_pCurrentPick->getWorldPosition() + size * vDirReal );

	// make two 2D vector
	Vec2 vCenter(vCenter3D.x, vCenter3D.y);
	Vec2 vAxis(vAxis3D.x, vAxis3D.y);

	Vec2 vPoint = vCursor - vCenter;
	Vec2 vAxisPoint = vAxis - vCenter;

	ms_dragInvertX = vAxisPoint.x > 0 ? 1 : -1;
	ms_dragInvertY = vAxisPoint.y > 0 ? 1 : -1;

	// judge this
	if (vPoint.GetLength() - vAxisPoint.GetLength() < size + 2.0f)
	{
		vPoint.Normalize();
		vAxisPoint.Normalize();

		if (vPoint.Dot(vAxisPoint) > 0.95f)
			return true;
	}

	return false;
}
Пример #2
0
/**
 * Find and apply the force between the two bodies muscle is attached to.
 *
 * returns the magnitude of this force.
 */
float Muscle::update () const {
    Vec2 a1W = body1->GetWorldPoint(end1L);
    Vec2 a2W = body2->GetWorldPoint(end2L);

    Vec2 diff = a1W - a2W;
    float length = diff.Normalize();
    //XXX check if length == 0?
    //diff now normalized, points from a2->a1
    //diff *= 1.0f/length;
    
    //Now find how far we are from equilibrium to determine spring force
    float force = k*(eq-length);

    //Also apply dampening
    // find relative velocity of two points
    Vec2 vel = body1->GetLinearVelocityFromLocalPoint(end1L) - 
	       body2->GetLinearVelocityFromLocalPoint(end2L);
    force -= kd * b2Dot(vel, diff);

    diff *= force;

    //Now apply force to body1
    body1->ApplyForce(diff, a1W);

    //Reverse force, and apply to body2
    diff *= -1;
    body2->ApplyForce(diff, a2W);

    return force;
}
Пример #3
0
void Boid::AvoidWalls()
{
	for (GameObject* obj = GameObject::All(); obj != NULL; obj = obj->GetNext())
	{
		// do strong separation for walls
		if (obj->GetType() == GameObject::TWall)
		{
			Vec2 delta = GetPosition() - obj->GetPosition();
			float dist = delta.Length();
			if (dist < 2.f && dist > 0.f)
				AddForce(Steer(delta.Normalize() / dist));
		}
	}

	// avoid outer walls
	Vec2 steer;

	if (GetPosition().x < 1.f)
		steer += Steer(Vec2(1.f, 0.f));
	if (GetPosition().x > 19.f)
		steer += Steer(Vec2(-1.f, 0.f));
	if (GetPosition().y < 1.f)
		steer += Steer(Vec2(0.f, 1.f));
	if (GetPosition().y > 14.f)
		steer += Steer(Vec2(0.f, -1.f));

	AddForce(2.f * steer);
}
Пример #4
0
void Boid::Collision(GameObject* other, const Vec2& point, const Vec2& normal)
{
	if (other->GetType() == TPlayer)
	{
		// bounce effect
		Vec2 normal = other->GetPosition() - GetPosition();
		normal = normal.Normalize();

		Vec2 relVel = other->GetVelocity() - GetVelocity();
		float relVelMag = relVel.Length();

		float mass = GetMass() + other->GetMass();

		Vec2 pVel = other->GetVelocity();
		pVel += -normal * ((Player*)other)->GetShieldForce();

		Vec2 v1 = ((GetMass() - other->GetMass()) / mass) * GetVelocity() + (2.f * other->GetMass() / mass) * pVel - GetVelocity();
		Vec2 v2 = ((other->GetMass() - GetMass()) / mass) * other->GetVelocity() + (2.f * GetMass() / mass) * GetVelocity() - other->GetVelocity();
		AddForce(v1 / g_FrameTime);
		other->AddForce(v2 / g_FrameTime);

		SetPosition(other->GetPosition() + -normal * (GetScale() + other->GetScale() * 0.5f));
	}
	else if (other->GetType() == TBoid)
	{
		m_Anger += g_FrameTime;
	}
	else if (other->GetType() == TWall)
	{
		if (GetVelocity().Length() > 4.f)
			Destroy();
	}
}
Пример #5
0
Vec2 Boid::Flock(BoidFriend* boids, int count)
{
	Vec2 cohesion, alignment, separation;

	// average the positions and velocities of all boids in area
	int sepCount = 0;

	for (int i = 0; i != count; ++i)
	{
		cohesion += boids[i].boid->GetPosition() - GetPosition();
		alignment += boids[i].boid->GetVelocity();

		if (boids[i].distance < 1.25f)
		{
			Vec2 delta = (GetPosition() - boids[i].boid->GetPosition());
			if (!delta.IsZero())
			{
				separation += delta.Normalize() / boids[i].distance;
				++sepCount;
			}
		}
	}

	if (count != 0)
	{
		cohesion /= count;
		alignment /= count;
	}

	if (sepCount != 0)
		separation /= sepCount;

	return Steer(cohesion) + Steer(alignment) + Steer(separation);
}
Пример #6
0
bool RopeJoint::SolvePositionConstraints(const SolverData& data)
{
	Vec2 cA = data.positions[m_indexA].c;
	float32 aA = data.positions[m_indexA].a;
	Vec2 cB = data.positions[m_indexB].c;
	float32 aB = data.positions[m_indexB].a;

	Rot qA(aA), qB(aB);

	Vec2 rA = Mul(qA, m_localAnchorA - m_localCenterA);
	Vec2 rB = Mul(qB, m_localAnchorB - m_localCenterB);
	Vec2 u = cB + rB - cA - rA;

	float32 length = u.Normalize();
	float32 C = length - m_maxLength;

	C = Clamp(C, 0.0f, maxLinearCorrection);

	float32 impulse = -m_mass * C;
	Vec2 P = impulse * u;

	cA -= m_invMassA * P;
	aA -= m_invIA * Cross(rA, P);
	cB += m_invMassB * P;
	aB += m_invIB * Cross(rB, P);

	data.positions[m_indexA].c = cA;
	data.positions[m_indexA].a = aA;
	data.positions[m_indexB].c = cB;
	data.positions[m_indexB].a = aB;

	return length - m_maxLength < linearSlop;
}
Пример #7
0
Vec2 Boid::Steer(const Vec2& target) const
{
	if (!target.IsZero())
	{
		Vec2 dir = target.Normalize();
		dir *= m_MaxSpeed;
		Vec2 steer = dir - GetVelocity();
		steer = steer.Clamp(m_MaxSteeringForce);
		return steer;
	}
	else
		return Vec2();
}
Пример #8
0
void Postprocessing_UpdateQuake(float deltaTime)
{
	if (!quake->enabled)
		return;

	quake->time += deltaTime;

	// Update quake

	bool toCenter = true;

	if (quake->time - quake->lastHitTime > quake->hitLength)
	{
		const float hitSizeX = 0.02f;
		const float hitSizeY = 0.1f;

		const float startFadeOutTime = 0.2f;
		const float fadeOutTime = 0.15f;

		quake->targetOffset.Set(
			hitSizeX * ((Random::GetInt() & 1) ? 1.0f : -1.0f),
			hitSizeY * ((Random::GetInt() & 1) ? 1.0f : -1.0f));
		if (quake->lastHitTime > startFadeOutTime)
		{
			quake->targetOffset *= max(0.0f, (fadeOutTime - (quake->lastHitTime - startFadeOutTime)) / fadeOutTime);
		}

		quake->lastHitTime = quake->time;
		quake->hitLength = Random::GetFloat(0.1f, 0.1f);

		if (toCenter)
			quake->offset = quake->targetOffset;
	}

	Vec2 toTargetDir;
	if (toCenter)
		toTargetDir = Vec2(0, 0) - quake->offset;
	else
		toTargetDir = quake->targetOffset - quake->offset;
	float toTargetLength = toTargetDir.Length();
	toTargetDir.Normalize();

	float moveBy = clamp(toTargetLength, 0.0f, (toCenter ? 0.8f : 1.0f) * deltaTime);

	quake->offset += toTargetDir * moveBy;

	if (quake->offset.Length() <= 0.001f)
		quake->enabled = false;
}
Пример #9
0
bool DistanceJoint::SolvePositionConstraints(const SolverData& data)
{
	if (m_frequencyHz > 0.0f)
	{
		// There is no position correction for soft distance constraints.
		return true;
	}

	Vec2 cA = data.positions[m_indexA].c;
	float32 aA = data.positions[m_indexA].a;
	Vec2 cB = data.positions[m_indexB].c;
	float32 aB = data.positions[m_indexB].a;

	Rot qA(aA), qB(aB);

	Vec2 rA = Mul(qA, m_localAnchorA - m_localCenterA);
	Vec2 rB = Mul(qB, m_localAnchorB - m_localCenterB);
	Vec2 u = cB + rB - cA - rA;

	float32 length = u.Normalize();
	float32 C = length - m_length;
	C = Clamp(C, -maxLinearCorrection, maxLinearCorrection);

	float32 impulse = -m_mass * C;
	Vec2 P = impulse * u;

	cA -= m_invMassA * P;
	aA -= m_invIA * Cross(rA, P);
	cB += m_invMassB * P;
	aB += m_invIB * Cross(rB, P);

	data.positions[m_indexA].c = cA;
	data.positions[m_indexA].a = aA;
	data.positions[m_indexB].c = cB;
	data.positions[m_indexB].a = aB;

	return Abs(C) < linearSlop;
}
Пример #10
0
int main(int argc, char** argv) {
	GLFWwindow* window;
	if (!glfwInit()) {
		std::cout << "Failed to init GLFW!" << std::endl;
		return EXIT_FAILURE;
	}
	window = glfwCreateWindow(WIDTH, HEIGHT, "OpenGL", nullptr, nullptr);

	if (!window)
	{
		std::cout << "Failed to create GLFW window!" << std::endl;
		return EXIT_FAILURE;
	}

	glfwMakeContextCurrent(window);
	glewInit();

	Shader vert = Shader(GL_VERTEX_SHADER, "data/shaders/basic.vert");
	Shader frag = Shader(GL_FRAGMENT_SHADER, "data/shaders/fractal.frag");

	ShaderProgram program = ShaderProgram(vert, frag);
	program.Enable();

	Vec2 size = Vec2(800, 600);
	std::cout << size << std::endl;
	Log(size.Length());
	Log(size.Normalize());

	std::vector<Vec2> verticies;
	verticies.push_back(Vec2(-1, 1));
	verticies.push_back(Vec2(1, 1));
	verticies.push_back(Vec2(-1, -1));
	verticies.push_back(Vec2(1, -1));
	Vec2 test;
	test = test.Normalize(verticies[0]);

	Log(test);
	Log(test.AngleRadians());
	Log(test.AngleDegrees());

	GLint sizeID = glGetUniformLocation(program.ID(), "uSize");
	glUniform2f(sizeID, WIDTH, HEIGHT);
	GLint offset = glGetUniformLocation(program.ID(), "offset");
	glUniform2f(offset, 0,0);
	GLint scale = glGetUniformLocation(program.ID(), "scale");
	glUniform1f(scale, 2.0f);

	while (!glfwWindowShouldClose(window))
	{
		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		glBegin(GL_TRIANGLE_STRIP);
		for (size_t i = 0; i < verticies.size(); i++)
		{
			glVertex2f(verticies[i].X,verticies[i].Y);
		}
		glEnd();
		glfwSwapBuffers(window);
		glfwPollEvents();
	}
	glfwTerminate();
	std::cin.ignore();
	return 0;

}
Пример #11
0
Direction GetRotationDirection(Vec2 heading, Vec2 target) {
    Vec2 perp = heading.Perpendicular();
    target.Normalize();
    return perp.Dot(target) >= 0.0 ? Direction::Right : Direction::Left;
}
Пример #12
0
/*
=============
  SetPointList
  Точки необходимо задавать обходя по часовой стрелке
=============
*/
void CollisionElementPolygon::SetPointList( const PointList &setPoints ) {
  if( setPoints.size() < 3 ) {
    __log.PrintInfo( Filelevel_ERROR, "CollisionElementPolygon::SetPointList => not enough points" );
    return;
  }
  this->pointsSource = setPoints;
  this->pointsResult.clear();
  this->pointsResult.resize( setPoints.size() + 1 );

  //copy src to result
  int num = 0;
  PointList::iterator iter, iterEnd = this->pointsSource.end();
  for( iter = this->pointsSource.begin(); iter != iterEnd; ++iter, ++num ) {
    this->pointsResult[ num ] = *iter;
  }
  this->pointsResult[ this->pointsResult.size() - 1 ] = this->pointsSource[ 0 ];

  Vec2 radiusVector( Vec2Null );
  Vec2 edge0, edge1, edge2;
  num = 0;
  iterEnd = this->pointsResult.end();
  for( iter = this->pointsResult.begin(); iter != iterEnd; ++iter, ++num ) {
    Point *point = &( *iter );
    radiusVector.Set( max( fabs( point->x ), radiusVector.x ), max( fabs( point->y ), radiusVector.y ) );
    if( num > 1 ) {
      //нормальзовать не нужно т.к. нужно не значение, а только знак
      edge0 = this->pointsResult[ num - 1 ] - this->pointsResult[ num - 2 ];
      edge1 = this->pointsResult[ num ] - this->pointsResult[ num - 2 ];
      edge1.Rotate90CW();
      float sign = edge0.Dot( edge1 );
      if( sign > 0 ) {
        __log.PrintInfo( Filelevel_ERROR, "CollisionElementPolygon::SetPointList => points[%d] is not clockwise", num );
        this->pointsResult.clear();
        this->pointsSource.clear();
        return;
      }
    }
  }//for
  this->_rect->radius2 = Square( radiusVector.Length() );

  //формирования списка разделающих осей
  Vec2 axis;
  Vec2 tmpVec2;
  iterEnd = this->pointsResult.end();
  iter = this->pointsResult.begin();
  num = 1;
  for( ++iter; iter != iterEnd; ++iter, ++num ) {
    tmpVec2 = this->pointsResult[ num ] - this->pointsResult[ num - 1 ];
    axis.Set( tmpVec2.x, tmpVec2.y );
    axis.Rotate90CW();
    if( axis.x < 0 ) {
      axis *= -1.0f;
    } else if( axis.y < 0.0f ) {
      axis *= -1.0f;
    }
    axis.Normalize();
    if( !this->_IsAxisExists( axis ) ) {
      this->axes.push_back( axis );
    }
  }//foreach pointsSource
}//SetPointList
Пример #13
0
void Manifold::ApplyImpulse( void )
{
  // Early out and positional correct if both objects have infinite mass
  if(Equal( A->im + B->im, 0 ))
  {
    InfiniteMassCorrection( );
    return;
  }

  for(uint32 i = 0; i < contact_count; ++i)
  {
    // Calculate radii from COM to contact
    Vec2 ra = contacts[i] - A->position;
    Vec2 rb = contacts[i] - B->position;

    // Relative velocity
    Vec2 rv = B->velocity + Cross( B->angularVelocity, rb ) -
              A->velocity - Cross( A->angularVelocity, ra );

    // Relative velocity along the normal
    real contactVel = Dot( rv, normal );

    // Do not resolve if velocities are separating
    if(contactVel > 0)
      return;

    real raCrossN = Cross( ra, normal );
    real rbCrossN = Cross( rb, normal );
    real invMassSum = A->im + B->im + Sqr( raCrossN ) * A->iI + Sqr( rbCrossN ) * B->iI;

    // Calculate impulse scalar
    real j = -(1.0f + e) * contactVel;
    j /= invMassSum;
    j /= (real)contact_count;

    // Apply impulse
    Vec2 impulse = normal * j;
    A->ApplyImpulse( -impulse, ra );
    B->ApplyImpulse(  impulse, rb );

    // Friction impulse
    rv = B->velocity + Cross( B->angularVelocity, rb ) -
         A->velocity - Cross( A->angularVelocity, ra );

    Vec2 t = rv - (normal * Dot( rv, normal ));
    t.Normalize( );

    // j tangent magnitude
    real jt = -Dot( rv, t );
    jt /= invMassSum;
    jt /= (real)contact_count;

    // Don't apply tiny friction impulses
    if(Equal( jt, 0.0f ))
      return;

    // Coulumb's law
    Vec2 tangentImpulse;
    if(std::abs( jt ) < j * sf)
      tangentImpulse = t * jt;
    else
      tangentImpulse = t * -j * df;

    // Apply friction impulse
    A->ApplyImpulse( -tangentImpulse, ra );
    B->ApplyImpulse(  tangentImpulse, rb );
  }
}