//---------------------------------------------------------------------------- Vector2f RenderStep::PointWorldToViewPort(const APoint &point, bool *isInBack) { Rectf viewPort = mViewPort; if (viewPort.IsEmpty()) viewPort = Rectf(0.0f, 0.0f, mSize.Width, mSize.Height); HMatrix matProjView = mCamera->GetProjectionMatrix() * mCamera->GetViewMatrix(); HPoint hPoint(point.X(), point.Y(), point.Z(), point.W()); HPoint tempPoint = matProjView * hPoint; if (isInBack) { if (tempPoint.Z() <= 0) *isInBack = true; else *isInBack = false; } float wInv = 1.0f / tempPoint.W(); //投影坐标范围为[-1,1]要变成[0,1] Vector2f screenPoint; screenPoint.X() = (1.0f + tempPoint.X()*wInv) / 2.0f; screenPoint.Y() = (1.0f + tempPoint.Y()*wInv) / 2.0f; //投影坐标范围为[0,1]要变成视口内坐标 screenPoint.X() = viewPort.Left + screenPoint.X()*viewPort.Width(); screenPoint.Y() = viewPort.Bottom + screenPoint.Y()*viewPort.Height(); return screenPoint; }
//---------------------------------------------------------------------------- std::pair<float, float> EU_CanvasStage::CalPixelToWorld() { Rectf viewPort = mViewPort; if (viewPort.IsEmpty()) viewPort = Rectf(0.0f, 0.0f, mSize.Width, mSize.Height); std::pair<float, float> pixelToWorld; if (mStageCameraNode) { Camera *camera = mStageCameraNode->GetCamera(); float rMin = camera->GetRMin(); float uMin = camera->GetUMin(); float viewPortWidth = viewPort.Width(); float viewPortHeight = viewPort.Height(); float worldW = 2.0f * -rMin; float worldH = 2.0f * -uMin; worldW *= 1000.0f; worldH *= 1000.0f; pixelToWorld.first = worldW / (float)viewPortWidth; pixelToWorld.second = worldH / (float)viewPortHeight; } mPixelToWorld = pixelToWorld; return mPixelToWorld; }
//---------------------------------------------------------------------------- bool RenderStep::GetPickRay(float x, float y, APoint& origin, AVector& direction) { if (!mCamera) return false; Rectf viewPort = mViewPort; if (viewPort.IsEmpty()) viewPort = Rectf(0.0f, 0.0f, mSize.Width, mSize.Height); if (viewPort.IsEmpty()) return false; // Get the current viewport and test whether (x,y) is in it. float viewX = viewPort.Left; float viewY = viewPort.Bottom; float viewW = viewPort.Width(); float viewH = viewPort.Height(); // Get the [0,1]^2-normalized coordinates of (x,y). float r = ((float)(x - viewX)) / (float)viewW; float u = ((float)(y - viewY)) / (float)viewH; // Get the relative coordinates in [rmin,rmax]x[umin,umax]. float rBlend = (1.0f - r)*mCamera->GetRMin() + r*mCamera->GetRMax(); float uBlend = (1.0f - u)*mCamera->GetUMin() + u*mCamera->GetUMax(); if (mCamera->IsPerspective()) { origin = mCamera->GetPosition(); direction = mCamera->GetDMin()*mCamera->GetDVector() + rBlend*mCamera->GetRVector() + uBlend*mCamera->GetUVector(); direction.Normalize(); } else { origin = mCamera->GetPosition() + rBlend*mCamera->GetRVector() + uBlend*mCamera->GetUVector(); direction = mCamera->GetDVector(); direction.Normalize(); } return true; }
//---------------------------------------------------------------------------- std::pair<float, float> RenderStep::CalPixelToWorld() { Rectf viewPort = mViewPort; if (viewPort.IsEmpty()) viewPort = Rectf(0.0f, 0.0f, mSize.Width, mSize.Height); std::pair<float, float> pixelToWorld; if (mCamera) { if (mCamera->IsPerspective()) { float rMin = mCamera->GetRMin(); float uMin = mCamera->GetUMin(); float viewPortWidth = viewPort.Width(); float viewPortHeight = viewPort.Height(); float worldW = 2.0f * -rMin; float worldH = 2.0f * -uMin; worldW *= 10.0f; worldH *= 10.0f; pixelToWorld.first = worldW / (float)viewPortWidth; pixelToWorld.second = worldH / (float)viewPortHeight; } else { float rMin = mCamera->GetRMin(); float uMin = mCamera->GetUMin(); float viewPortWidth = viewPort.Width(); float viewPortHeight = viewPort.Height(); float worldW = 2.0f * -rMin; float worldH = 2.0f * -uMin; worldW *= 1.0f; worldH *= 1.0f; pixelToWorld.first = worldW / (float)viewPortWidth; pixelToWorld.second = worldH / (float)viewPortHeight; } } return pixelToWorld; }
//---------------------------------------------------------------------------- void RenderStep::Draw() { if (!IsEnable()) return; if (mRenderer) { CameraPtr beforeCamer = mRenderer->GetCamera(); mRenderer->InitRenderStates(); Rectf viewPort = mViewPort; if (viewPort.IsEmpty()) viewPort = Rectf(0.0f, 0.0f, mSize.Width, mSize.Height); mRenderer->SetViewport(viewPort); if (mIsDoClearDepth) mRenderer->ClearDepthBuffer(); mRenderer->SetCamera(mCamera); mRenderer->Draw(mCuller.GetVisibleSet()); mRenderer->SetCamera(beforeCamer); } }
//---------------------------------------------------------------------------- void UICurveGroup::OnUIPicked(const UIInputData &inputData) { const APoint &worldPos = inputData.WorldPos; Float2 wPos(worldPos.X(), worldPos.Z()); UIFrame *parentFrame = DynamicCast<UIFrame>(GetParent()); if (parentFrame) { const Rectf &parentRect = parentFrame->GetWorldRect(); if (!parentRect.IsInsize(wPos)) { return; } } if (UIInputData::MT_LEFT == inputData.TheMouseTag && UIPT_RELEASED == inputData.PickType) { Rectf rect0; if (mBox0) rect0 = mBox0->GetWorldRect(); Rectf rect1; if (mBox1) rect1 = mBox1->GetWorldRect(); Rectf rect2; if (mBox2) rect2 = mBox2->GetWorldRect(); Rectf rect3; if (mBox3) rect3 = mBox3->GetWorldRect(); Rectf rect4; if (mBox4) rect4 = mBox4->GetWorldRect(); Rectf rect5; if (mBox5) rect5 = mBox5->GetWorldRect(); Rectf rect; if (mBox) rect = mBox->GetWorldRect(); if (!rect0.IsEmpty() && rect0.IsInsize(wPos)) { mIsShowBox0 = !mIsShowBox0; if (mIsShowBox0) { mBox0->SetColor(Float3::RED); mIsShowBox = true; mBox->SetColor(Float3::YELLOW); } else mBox0->SetColor(Float3(0.5f, 0.5f, 0.5f)); mCurveGroup->SetVisible(0, mIsShowBox0); } else if (!rect1.IsEmpty() && rect1.IsInsize(wPos)) { mIsShowBox1 = !mIsShowBox1; if (mIsShowBox1) { mBox1->SetColor(Float3::GREEN); mIsShowBox = true; mBox->SetColor(Float3::YELLOW); } else mBox1->SetColor(Float3(0.5f, 0.5f, 0.5f)); mCurveGroup->SetVisible(1, mIsShowBox1); } else if (!rect2.IsEmpty() && rect2.IsInsize(wPos)) { mIsShowBox2 = !mIsShowBox2; if (mIsShowBox2) { mBox2->SetColor(Float3::BLUE); mIsShowBox = true; mBox->SetColor(Float3::YELLOW); } else mBox2->SetColor(Float3(0.5f, 0.5f, 0.5f)); mCurveGroup->SetVisible(2, mIsShowBox2); } else if (!rect3.IsEmpty() && rect3.IsInsize(wPos)) { mIsShowBox3 = !mIsShowBox3; if (mIsShowBox3) { mBox3->SetColor(Float3::RED / 2.0f); mIsShowBox = true; mBox->SetColor(Float3::YELLOW); } else mBox3->SetColor(Float3(0.5f, 0.5f, 0.5f)); mCurveGroup->SetVisible(3, mIsShowBox3); } else if (!rect4.IsEmpty() && rect4.IsInsize(wPos)) { mIsShowBox4 = !mIsShowBox4; if (mIsShowBox4) { mBox4->SetColor(Float3::GREEN / 2.0f); mIsShowBox = true; mBox->SetColor(Float3::YELLOW); } else mBox4->SetColor(Float3(0.5f, 0.5f, 0.5f)); mCurveGroup->SetVisible(4, mIsShowBox4); } else if (!rect5.IsEmpty() && rect5.IsInsize(wPos)) { mIsShowBox5 = !mIsShowBox5; if (mIsShowBox5) { mBox5->SetColor(Float3::BLUE / 2.0f); mIsShowBox = true; mBox->SetColor(Float3::YELLOW); } else mBox5->SetColor(Float3(0.5f, 0.5f, 0.5f)); mCurveGroup->SetVisible(5, mIsShowBox5); } else if (!rect.IsEmpty() && rect.IsInsize(wPos)) { mIsShowBox = !mIsShowBox; if (mIsShowBox) { if (mBox0) mBox0->SetColor(Float3::RED); if (mBox1) mBox1->SetColor(Float3::GREEN); if (mBox2) mBox2->SetColor(Float3::BLUE); if (mBox3) mBox3->SetColor(Float3::RED / 2.0f); if (mBox4) mBox4->SetColor(Float3::GREEN / 2.0f); if (mBox5) mBox5->SetColor(Float3::BLUE / 2.0f); mBox->SetColor(Float3::YELLOW); } else { if (mBox0) mBox0->SetColor(Float3(0.5f, 0.5f, 0.5f)); if (mBox1) mBox1->SetColor(Float3(0.5f, 0.5f, 0.5f)); if (mBox2) mBox2->SetColor(Float3(0.5f, 0.5f, 0.5f)); if (mBox3) mBox3->SetColor(Float3(0.5f, 0.5f, 0.5f)); if (mBox4) mBox4->SetColor(Float3(0.5f, 0.5f, 0.5f)); if (mBox5) mBox5->SetColor(Float3(0.5f, 0.5f, 0.5f)); mBox->SetColor(Float3(0.5f, 0.5f, 0.5f)); } mCurveGroup->SetVisible(mIsShowBox); } } }