void DrawPolygon(int indexTri) { vector<glm::vec3> vertice(3); vertice[0]=triangles[indexTri].v0; vertice[1]=triangles[indexTri].v1; vertice[2]=triangles[indexTri].v2; vector<PIXEL> projectedVertice(3); vertex.Normal = triangles[indexTri].normal; vertex.reflectance = triangles[indexTri].color; for( int indexVer=0; indexVer<3; ++indexVer ) { vertice[indexVer]= Rotation(vertice[indexVer]); projectedVertice[indexVer].position2D= VertexShader(vertice[indexVer]); projectedVertice[indexVer].zinv = 1/(vertice[indexVer].z-cameraPos.z); projectedVertice[indexVer].position3D = (vertice[indexVer]-cameraPos)*projectedVertice[indexVer].zinv; //projectedVertice[indexVer].illumination = Lighting(indexTri, indexVer,vertice); } int MAX=max(max(projectedVertice[0].position2D.y, projectedVertice[1].position2D.y), projectedVertice[2].position2D.y); int MIN=min(min(projectedVertice[0].position2D.y, projectedVertice[1].position2D.y),projectedVertice[2].position2D.y); int ROWS = MAX-MIN+1; vector<PIXEL> leftPixels(ROWS); vector<PIXEL> rightPixels(ROWS); // vec3 currentcolor=triangles[indexTri].color; for( int i=0; i<ROWS; ++i ) { leftPixels[i].position2D=ivec2(+numeric_limits<int>::max(),MIN+i); rightPixels[i].position2D=ivec2(-numeric_limits<int>::max(),MIN+i); } ComputePolygonRows(leftPixels, rightPixels, projectedVertice, ROWS); DrawPolygonRows(ROWS, leftPixels, rightPixels); }
void Picking::CalculateFrustum( const Camera& camera, const glm::ivec2& windowSize, const glm::mat4& invViewProj, const glm::ivec2& startPixel, const glm::ivec2& sizeInPixels, Frustum* outFrustum ) const { Ray cornerRays[4]; // Specific order of corner rays makes creating frustum planes in loops easier for me. const std::pair<int,int> order[4] = { std::pair<int,int>( 0, 0 ), std::pair<int,int>( 1, 0 ), std::pair<int,int>( 1, 1 ), std::pair<int,int>( 0, 1 ), }; // Create a ray for each corner of the box selection frustum. for ( int i = 0; i < 4; ++i ) { const int x = order[i].first; const int y = order[i].second; const ivec2 pixel = startPixel + ivec2( x * sizeInPixels.x, y * sizeInPixels.y); CalculateRayFromPixel( pixel, windowSize, invViewProj, &cornerRays[i] ); } // Calculate side frustum planes from the corner rays values. for ( int i = 0; i < 4; ++i ) { const int neighbourIndex = (i+1) % 4; const vec3 v1 = cornerRays[neighbourIndex].Position - cornerRays[i].Position; const vec3 v2 = cornerRays[i].Direction; outFrustum->Normals[i] = glm::normalize( glm::cross( v1, v2 ) ); outFrustum->Positions[i] = cornerRays[i].Position; } // Calculate near frustrum plane from the corner rays values. { const vec3 v1 = cornerRays[0].Position - cornerRays[1].Position; const vec3 v2 = cornerRays[2].Position - cornerRays[1].Position; outFrustum->Normals[4] = glm::normalize( glm::cross( v1, v2 ) ); outFrustum->Positions[4] = cornerRays[1].Position; } // Calculate far frustrum plane from the corner rays values. { const float cameraFar = camera.GetLens().Far; const vec3 farPoint[3] = { cornerRays[0].Position + cameraFar * cornerRays[0].Direction, cornerRays[1].Position + cameraFar * cornerRays[1].Direction, cornerRays[2].Position + cameraFar * cornerRays[2].Direction, }; const vec3 v1 = farPoint[2] - farPoint[1]; const vec3 v2 = farPoint[0] - farPoint[1]; outFrustum->Normals[5] = glm::normalize( glm::cross( v1, v2 ) ); outFrustum->Positions[5] = farPoint[1]; } }
void Interpolate( PIXEL a, PIXEL b, vector<PIXEL>& result) { int N = result.size(); vec2 step1 = vec2(b.position2D-a.position2D) / float(max(N-1,1)); vec2 current1= vec2(a.position2D); float step2 = (b.zinv-a.zinv)/float(max(N-1,1)); float current2 = a.zinv; // vec3 step3 = (b.illumination - a.illumination)/ float(max(N-1,1)); // vec3 current3 = a.illumination; vec3 step4 =(b.position3D - a.position3D)/ float(max(N-1,1)); vec3 current4= a.position3D; for( int i=0; i<N; ++i ) { result[i].position2D =ivec2(current1); result[i].zinv = current2; // result[i].illumination = current3; result[i].position3D = current4; current1 = step1+current1; current2 = step2+current2; // current3 = step3+current3; current4 = step4+current4; } }
void Picking::PickFrustum( const rVector<int>& targetGroups, const Camera& camera, const glm::ivec2& startPixel, const glm::ivec2& sizeInPixels ) { const ivec2 windowSize = ivec2( camera.GetLens().WindowWidth, camera.GetLens().WindowHeight ); const mat4 invViewProj = glm::inverse( camera.GetViewProjection() ); Frustum frustum; CalculateFrustum( camera, windowSize, invViewProj, startPixel, sizeInPixels, &frustum ); g_CollisionDetection.PickingWithFrustum( frustum.Positions, frustum.Normals, targetGroups, m_UnitsSelected) ; }
void Picking::PickRay( const rVector<int>& targetGroups, const Camera& camera, const glm::ivec2& pixel ) { const ivec2 windowSize = ivec2( camera.GetLens().WindowWidth, camera.GetLens().WindowHeight ); const mat4 invViewProj = glm::inverse( camera.GetViewProjection() ); Ray ray; CalculateRayFromPixel( pixel, windowSize, invViewProj, &ray ); g_CollisionDetection.PickingWithRay( ray.Position, ray.Direction, targetGroups, m_UnitsSelected, &m_ClickedPosition ); }
void easygl::movemouse(double x, double y){ mouse = ivec2(x, y); vec3 screen=vec3(x,viewportSize.y - y,zbuf); vec3 pos= unProject(screen,dragmodelview,projection,vec4(0,0, viewportSize.x, viewportSize.y)); glmouse = vec2(pos.x,pos.y); if(dragl && screen.z != 1) { vec2 gldiff = (gllastmouse - glmouse); movement -= glm::vec3(gldiff,0); }else{ dragmodelview = modelview; glReadPixels(x,viewportSize.y - y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&zbuf); } gllastmouse = glmouse; lastMouse = mouse; }
void Picking::Update( const Camera& camera, PickingAction& outAction ) { outAction = PickingAction::None; m_UnitsSelected.clear(); ivec2 mousePosition( g_Input->GetMousePosX(), g_Input->GetMousePosY() ); // Start boxselecting. if ( g_Input->MouseUpDown( MOUSE_BUTTON_LEFT ) ) { m_BoxSelecting = true; m_FirstSelectionPoint = mousePosition; } // Update selection box position and size. if ( m_BoxSelecting ) { m_SelectionBox.Position = ivec2( glm::min( m_FirstSelectionPoint.x, mousePosition.x ), glm::min( m_FirstSelectionPoint.y, mousePosition.y ) ); m_SelectionBox.Size = ivec2( 1 + glm::abs( m_FirstSelectionPoint.x - mousePosition.x ), 1 + glm::abs( m_FirstSelectionPoint.y - mousePosition.y ) ); } // Do the actual picking. if ( g_Input->MouseUpDown( MOUSE_BUTTON_RIGHT ) ) { m_BoxSelecting = false; this->PickRay( m_RightClickGroups, camera, mousePosition ); } else if ( g_PlayerData.GetLastActionPressed() == ACTION::ACTION_AI_ATTACK ) { m_BoxSelecting = false; this->PickRay( m_AttackClickGroups, camera, mousePosition ); } else if ( g_PlayerData.GetLastActionPressed( ) == ACTION::ACTION_PING ) { m_BoxSelecting = false; } else if ( m_BoxSelecting && (this->m_SelectionBox.Size.x >= PICKING_FRUSTUM_MINIMUM || this->m_SelectionBox.Size.y >= PICKING_FRUSTUM_MINIMUM) ) { this->PickFrustum( m_BoxSelectionGroups, camera, m_SelectionBox.Position, m_SelectionBox.Size ); m_LastPickWasBox = true; } else { this->PickRay( m_LeftClickGroups, camera, mousePosition ); m_LastPickWasBox = false; } // Decide how to handle the picking result. if ( m_UnitsSelected.size() > 0 ) { if ( g_Input->MouseUpDown( MOUSE_BUTTON_RIGHT ) ) { if ( g_EntityManager.GetEntityMask( m_UnitsSelected[0] ) & DenseComponentCollection<CollisionComponent>::GetInstance().GetComponentTypeFlag() ) { CollisionComponent* collisionComp = GetDenseComponent<CollisionComponent>( m_UnitsSelected[0] ); if ( collisionComp->CollisionEntity->GetGroupID() == PICKING_TYPE_ENEMY ) { outAction = PickingAction::Attack; } else if ( collisionComp->CollisionEntity->GetGroupID() == PICKING_TYPE_RESOURCE ) { outAction = PickingAction::Gather; } else if ( collisionComp->CollisionEntity->GetGroupID() == PICKING_TYPE_TERRAIN ) { outAction = PickingAction::Move; m_UnitsSelected.clear(); } else if ( collisionComp->CollisionEntity->GetGroupID() == PICKING_TYPE_CONTROL_POINT ) { outAction = PickingAction::Capture; } } //reset attack key state g_PlayerData.SetLastActionPressed(ACTION_SIZE); } else if ( g_Input->MouseDownUp( MOUSE_BUTTON_LEFT ) ) { EntityMask entityMask = g_EntityManager.GetEntityMask( m_UnitsSelected[0] ); EntityMask collisionFlag = DenseComponentCollection<CollisionComponent>::GetInstance().GetComponentTypeFlag(); if ( g_PlayerData.GetLastActionPressed() == ACTION::ACTION_AI_ATTACK ) { if ( (entityMask & collisionFlag) && GetDenseComponent<CollisionComponent>( m_UnitsSelected[0] )->CollisionEntity->GetGroupID() == PICKING_TYPE_TERRAIN ) { outAction = PickingAction::AttackMove; m_UnitsSelected.clear(); } else { outAction = PickingAction::Attack; } if ( g_Input->KeyUp( SDL_SCANCODE_LSHIFT ) ) g_PlayerData.SetLastActionPressed(ACTION_SIZE); } else { if ( (entityMask & collisionFlag) && GetDenseComponent<CollisionComponent>( m_UnitsSelected[0] )->CollisionEntity->GetGroupID() == PICKING_TYPE_TERRAIN ) { outAction = PickingAction::UnitDeselect; m_UnitsSelected.clear(); } else { outAction = PickingAction::UnitSelection; } } } } if ( m_BoxSelecting && g_Input->MouseDownUp( MOUSE_BUTTON_LEFT, true ) ) { m_BoxSelecting = false; } }