//----------------------------------------------------------------------- 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; }
/** * 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; }
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); }
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(); } }
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); }
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; }
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(); }
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; }
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; }
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; }
Direction GetRotationDirection(Vec2 heading, Vec2 target) { Vec2 perp = heading.Perpendicular(); target.Normalize(); return perp.Dot(target) >= 0.0 ? Direction::Right : Direction::Left; }
/* ============= 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
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 ); } }