//-------------------------------------------------------------------------------------------------- // Name: ValidateExtractedOutline // Desc: Performs a final validation pass on the extracted outline //-------------------------------------------------------------------------------------------------- bool CBreakableGlassSystem::ValidateExtractedOutline(SBreakableGlassPhysData& data, SBreakableGlassInitParams& initParams) { bool valid = true; // Check for overlapping points (leads to FPE during triangulation) if (initParams.pInitialFrag && initParams.numInitialFragPts > 0) { const Vec2* pPts = initParams.pInitialFrag; const uint numEdges = initParams.numInitialFragPts-1; const float minEdgeLen = 0.0001f; for (uint i = 0, j = 1; i < numEdges; ++i, ++j) { const Vec2 edge(pPts[i] - pPts[j]); if (edge.GetLength2() < minEdgeLen) { LOG_GLASS_ERROR("Extracted mesh has invalid edges."); valid = false; break; } } } // Check for overlapping UVs (leads to FPE during uv basis calculation) if (valid) { const Vec2 uvPtA(data.uvBasis[0].x, data.uvBasis[0].y); const Vec2 uvPtB(data.uvBasis[1].x, data.uvBasis[1].y); const Vec2 uvPtC(data.uvBasis[2].x, data.uvBasis[2].y); const Vec2 uvEdge0(uvPtC - uvPtA); const Vec2 uvEdge1(uvPtB - uvPtA); const float dot00 = uvEdge0.Dot(uvEdge0); const float dot01 = uvEdge0.Dot(uvEdge1); const float dot11 = uvEdge1.Dot(uvEdge1); const float epsilon = 0.001f; if (fabs_tpl(dot00 * dot11 - dot01 * dot01) < epsilon) { LOG_GLASS_ERROR("Extracted mesh has invalid uv layout."); valid = false; } } return valid; }//-------------------------------------------------------------------------------------------------
/* ============= _ProjectObjectToAxis ============= */ void CollisionElementCircle::_ProjectObjectToAxis( const Vec2 &axis, FU_OUT float *min, FU_OUT float *max ) { if( !min || !max ) { return; } float center = axis.Dot( Vec2( this->position->x, this->position->y ) ); *min = center - this->diameter * 0.5f; *max = center + this->diameter * 0.5f; }//_ProjectObjectToAxis
void Wall::Collision(GameObject* other, const Vec2& point, const Vec2& normal) { // get collision normal and tangent Vec2 tangent = Vec2(-normal.y, normal.x); // calculate velocity of object, adjusting for player shield Vec2 vel = other->GetVelocity(); if (other->GetType() == TPlayer) vel += -normal * std::max(0.f, ((Player*)other)->GetShieldForce()); if (normal.Dot(vel) < 0.f) { Vec2 velocity = -normal * normal.Dot(vel) + tangent * tangent.Dot(vel); other->SetVelocity(velocity); } // push apart other->SetPosition(point + normal * other->GetScale() * 0.51f); }
/* ============= _ProjectObjectToAxis ============= */ void CollisionElementSquare::_ProjectObjectToAxis( const Vec2 &axis, FU_OUT float *min, FU_OUT float *max ) { if( !min || !max ) { return; } float resultPoints[ 4 ]; resultPoints[ 0 ] = axis.Dot( Vec2( this->_rect->leftTop.x, this->_rect->leftTop.y ) ); resultPoints[ 1 ] = axis.Dot( Vec2( this->_rect->rightBottom.x, this->_rect->leftTop.y ) ); resultPoints[ 2 ] = axis.Dot( Vec2( this->_rect->rightBottom.x, this->_rect->rightBottom.y ) ); resultPoints[ 3 ] = axis.Dot( Vec2( this->_rect->leftTop.x, this->_rect->rightBottom.y ) ); *min = *max = resultPoints[ 0 ]; for( int q = 1; q < 4; ++q ) { if( resultPoints[ q ] < *min ) { *min = resultPoints[ q ]; } if( resultPoints[ q ] > *max ) { *max = resultPoints[ q ]; } } }//_ProjectObjectToAxis
//----------------------------------------------------------------------- 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; }
Vec3 TapCamera::PointOnSphere( Vec2& point ) { Vec3 ball_mouse; float mag; Vec2 vec = (point - vec_ball_center_) / ball_radius_; mag = vec.Dot( vec ); if( mag > 1.f ) { float scale = 1.f / sqrtf( mag ); vec *= scale; ball_mouse = Vec3( vec, 0.f ); } else { ball_mouse = Vec3( vec, sqrtf( 1.f - mag ) ); } return ball_mouse; }
/* ============= _ProjectObjectToAxis ============= */ void CollisionElementPolygon::_ProjectObjectToAxis( const Vec2 &axis, FU_OUT float *min, FU_OUT float *max ) { if( !min || !max ) { return; } bool isInitialized = false; PointList::const_iterator iter, iterEnd = this->pointsResult.end(); for( iter = this->pointsResult.begin(); iter != iterEnd; ++iter ) { float dot = axis.Dot( *iter ); if( isInitialized ) { if( dot < *min ) { *min = dot; } else if( dot > *max ) { *max = dot; } } else { *min = *max = dot; isInitialized = true; } }//foreach pointsResult }//_ProjectObjectToAxis
Direction GetRotationDirection(Vec2 heading, Vec2 target) { Vec2 perp = heading.Perpendicular(); target.Normalize(); return perp.Dot(target) >= 0.0 ? Direction::Right : Direction::Left; }