void WASDCameraController::LookAtSelection() { DVASSERT(currScene); Camera * camera = currScene->GetCurrentCamera(); if (!camera)return; if ( !selection || dynamic_cast<Camera*>(selection) || dynamic_cast<LandscapeNode *>(selection) ) { return; } AABBox3 box = selection->GetWTMaximumBoundingBoxSlow(); float32 boxSize = ((box.max - box.min).Length()); const Vector3 & pos = camera->GetPosition(); const Vector3 & targ = camera->GetTarget(); Vector3 dir = targ - pos; dir.Normalize(); const Vector3 & c = box.GetCenter(); camera->SetTarget(c); camera->SetPosition(c - (dir * (boxSize + camera->GetZNear() * 1.5f))); }
void ScenePreviewControl::SetupCamera() { Camera *camera = editorScene->GetCamera(0); if (camera) { AABBox3 sceneBox = rootNode->GetWTMaximumBoundingBoxSlow(); Vector3 target = sceneBox.GetCenter(); camera->SetTarget(target); Vector3 dir = (sceneBox.max - sceneBox.min); float32 radius = dir.Length(); if(sceCamera) { radius = 5.f; } editorScene->SetCurrentCamera(camera); editorScene->SetClipCamera(camera); cameraController->SetScene(editorScene); cameraController->SetRadius(radius); cameraController->UpdateCamera(); } }
void WASDCameraController::Input(UIEvent * event) { if (currScene == 0) return; Camera * camera = currScene->GetCurrentCamera(); if (!camera)return; if (event->phase == UIEvent::PHASE_KEYCHAR) { if(!IsKeyModificatorsPressed()) { switch (event->tid) { case DVKEY_Z: { LookAtSelection(); break; } case DVKEY_T: { if (!camera)return; viewZAngle = 0; viewYAngle = MAX_ANGLE; Matrix4 mt, mt2; mt.CreateRotation(Vector3(0,0,1), DegToRad(viewZAngle)); mt2.CreateRotation(Vector3(1,0,0), DegToRad(viewYAngle)); mt2 *= mt; Vector3 vect = Vector3(0,0, 200); Vector3 position = vect + Vector3(0, 10, 0) * mt2; camera->SetTarget(position); camera->SetPosition(vect); break; } case DVKEY_1: { EditorSettings::Instance()->SetCameraSpeedIndex(0); SetSpeed(EditorSettings::Instance()->GetCameraSpeed()); break; } case DVKEY_2: { EditorSettings::Instance()->SetCameraSpeedIndex(1); SetSpeed(EditorSettings::Instance()->GetCameraSpeed()); break; } case DVKEY_3: { EditorSettings::Instance()->SetCameraSpeedIndex(2); SetSpeed(EditorSettings::Instance()->GetCameraSpeed()); break; } case DVKEY_4: { EditorSettings::Instance()->SetCameraSpeedIndex(3); SetSpeed(EditorSettings::Instance()->GetCameraSpeed()); break; } case DVKEY_9: { if (speed - 50 >= 0) { speed -= 50; } break; } case DVKEY_0: { if (speed + 50 <= 5000) { speed += 50; } break; } default: break; } } } bool altBut3 = (selection && event->tid == UIEvent::BUTTON_3 && IsKeyModificatorPressed(DVKEY_ALT)); if(UIEvent::PHASE_BEGAN == event->phase) { startPt = stopPt = event->point; if (altBut3) { const Vector3 & pos = camera->GetPosition(); AABBox3 box = selection->GetWTMaximumBoundingBoxSlow(); center = box.GetCenter(); radius = (center - pos).Length(); } } else if(UIEvent::PHASE_DRAG == event->phase || UIEvent::PHASE_ENDED == event->phase) { startPt = stopPt; stopPt = event->point; if (event->tid == UIEvent::BUTTON_2) { UpdateCam2But(camera); } else if (altBut3) { UpdateCamAlt3But(camera); } else if (event->tid == UIEvent::BUTTON_3) { UpdateCam3But(camera); } } }
void ImposterNode::UpdateState() { if(GetChildrenCount() > 0) { DVASSERT(GetChildrenCount() == 1); AABBox3 bbox = GetChild(0)->GetWTMaximumBoundingBoxSlow(); Vector3 bboxCenter = bbox.GetCenter(); float32 distanceSquare = (scene->GetCurrentCamera()->GetPosition() - bboxCenter).SquareLength(); distanceSquare *= scene->GetCurrentCamera()->GetZoomFactor() * scene->GetCurrentCamera()->GetZoomFactor(); Vector3 newDirection = scene->GetCurrentCamera()->GetPosition()-center; newDirection.Normalize(); float32 dotProduct = newDirection.DotProduct(direction); switch(state) { case STATE_3D: { if(distanceSquare > TOGGLE_SQUARE_DISTANCE) { UpdatePriority(distanceSquare, 0); AskForRedraw(); } else { isReady = false; } } break; case STATE_QUEUED: { if(IsAngleOrRangeChangedEnough(distanceSquare, dotProduct)) { UpdatePriority(distanceSquare, dotProduct); manager->UpdateQueue(this); } } break; case STATE_IMPOSTER: { if(distanceSquare < TOGGLE_SQUARE_DISTANCE) { isReady = false; state = STATE_3D; manager->RemoveFromQueue(this); break; } if(IsAngleOrRangeChangedEnough(distanceSquare, dotProduct)) { UpdatePriority(distanceSquare, dotProduct); AskForRedraw(); } } break; case STATE_REDRAW_APPROVED: { } break; } } }
void ImposterNode::UpdateImposter() { Camera * camera = scene->GetCurrentCamera(); Camera * imposterCamera = new Camera(); Vector3 cameraPos = camera->GetPosition(); Entity * child = GetChild(0); AABBox3 bbox = child->GetWTMaximumBoundingBoxSlow(); Vector3 bboxCenter = bbox.GetCenter(); imposterCamera->Setup(camera->GetFOV(), camera->GetAspect(), camera->GetZNear(), camera->GetZFar()); imposterCamera->SetTarget(bbox.GetCenter()); imposterCamera->SetPosition(cameraPos); imposterCamera->SetUp(camera->GetUp()); imposterCamera->SetLeft(camera->GetLeft()); Rect viewport = RenderManager::Instance()->GetViewport(); const Matrix4 & mvp = imposterCamera->GetUniformProjModelMatrix(); AABBox3 screenBounds; GetOOBBoxScreenCoords(child, mvp, screenBounds); Vector4 pv(bboxCenter); pv = pv*mvp; pv.z = (pv.z/pv.w + 1.f) * 0.5f; float32 bboxCenterZ = pv.z; Vector2 screenSize = Vector2(screenBounds.max.x-screenBounds.min.x, screenBounds.max.y-screenBounds.min.y); Vector3 screenBillboardVertices[4]; screenBillboardVertices[0] = Vector3(screenBounds.min.x, screenBounds.min.y, screenBounds.min.z); screenBillboardVertices[1] = Vector3(screenBounds.max.x, screenBounds.min.y, screenBounds.min.z); screenBillboardVertices[2] = Vector3(screenBounds.min.x, screenBounds.max.y, screenBounds.min.z); screenBillboardVertices[3] = Vector3(screenBounds.max.x, screenBounds.max.y, screenBounds.min.z); center = Vector3(); Matrix4 invMvp = mvp; invMvp.Inverse(); for(int32 i = 0; i < 4; ++i) { //unproject Vector4 out; out.x = 2.f*(screenBillboardVertices[i].x-viewport.x)/viewport.dx-1.f; out.y = 2.f*(screenBillboardVertices[i].y-viewport.y)/viewport.dy-1.f; out.z = 2.f*screenBillboardVertices[i].z-1.f; out.w = 1.f; out = out*invMvp; DVASSERT(out.w != 0.f); out.x /= out.w; out.y /= out.w; out.z /= out.w; imposterVertices[i] = Vector3(out.x, out.y, out.z); center += imposterVertices[i]; } center /= 4.f; //draw RecreateFbo(screenSize); //Logger::Info("%f, %f", screenSize.x, screenSize.y); if(!block) { return; } direction = camera->GetPosition()-center; direction.Normalize(); distanceSquaredToCamera = (center-cameraPos).SquareLength(); float32 nearPlane = sqrtf(distanceSquaredToCamera); //float32 farPlane = nearPlane + (bbox.max.z-bbox.min.z); float32 w = (imposterVertices[1]-imposterVertices[0]).Length(); float32 h = (imposterVertices[2]-imposterVertices[0]).Length(); //TODO: calculate instead of +50 imposterCamera->Setup(-w/2.f, w/2.f, -h/2.f, h/2.f, nearPlane, nearPlane+50.f); Rect oldViewport = RenderManager::Instance()->GetViewport(); //Texture * target = fbo->GetTexture(); RenderManager::Instance()->AppendState(RenderState::STATE_SCISSOR_TEST); RenderManager::Instance()->State()->SetScissorRect(Rect(block->offset.x, block->offset.y, block->size.dx, block->size.dy)); RenderManager::Instance()->FlushState(); //TODO: use one "clear" function instead of two //if(block->size.x == 512.f) //{ // RenderManager::Instance()->ClearWithColor(0.f, .8f, 0.f, 1.f); //} //else if(block->size.x == 256.f) //{ // RenderManager::Instance()->ClearWithColor(0.f, .3f, 0.f, 1.f); //} //else if(block->size.x == 128.f) //{ // RenderManager::Instance()->ClearWithColor(.3f, .3f, 0.f, 1.f); //} //else //{ // RenderManager::Instance()->ClearWithColor(.3f, 0.f, 0.f, 1.f); //} RenderManager::Instance()->ClearWithColor(.0f, .0f, 0.f, .0f); RenderManager::Instance()->ClearDepthBuffer(); RenderManager::Instance()->RemoveState(RenderState::STATE_SCISSOR_TEST); RenderManager::Instance()->SetViewport(Rect(block->offset.x, block->offset.y, block->size.dx, block->size.dy), true); imposterCamera->SetTarget(center); imposterCamera->Set(); //TODO: remove this call HierarchicalRemoveCull(child); RenderManager::Instance()->FlushState(); child->Draw(); RenderManager::Instance()->SetViewport(oldViewport, true); isReady = true; state = STATE_IMPOSTER; //unproject screenBillboardVertices[0] = Vector3(screenBounds.min.x, screenBounds.min.y, bboxCenterZ); screenBillboardVertices[1] = Vector3(screenBounds.max.x, screenBounds.min.y, bboxCenterZ); screenBillboardVertices[2] = Vector3(screenBounds.min.x, screenBounds.max.y, bboxCenterZ); screenBillboardVertices[3] = Vector3(screenBounds.max.x, screenBounds.max.y, bboxCenterZ); for(int32 i = 0; i < 4; ++i) { //unproject Vector4 out; out.x = 2.f*(screenBillboardVertices[i].x-viewport.x)/viewport.dx-1.f; out.y = 2.f*(screenBillboardVertices[i].y-viewport.y)/viewport.dy-1.f; out.z = 2.f*screenBillboardVertices[i].z-1.f; out.w = 1.f; out = out*invMvp; DVASSERT(out.w != 0.f); out.x /= out.w; out.y /= out.w; out.z /= out.w; imposterVertices[i] = Vector3(out.x, out.y, out.z); } SafeRelease(imposterCamera); ClearGeometry(); CreateGeometry(); }
void VegetationFixedGeometry::PrepareSortedIndexBufferVariations(size_t& currentIndexIndex, uint32 indexBufferIndex, size_t polygonElementCount, AABBox3& indexBufferBBox, Vector<Vector3>& directionPoints, Vector<Vector<VegetationSortedBufferItem> >& currentResolutionIndexArray, Vector<PolygonSortData>& sortingArray, Vector<VegetationIndex>& preparedIndices, VegetationRenderData& renderData) { size_t sortItemCount = preparedIndices.size() / polygonElementCount; sortingArray.resize(sortItemCount); for(size_t sortItemIndex = 0; sortItemIndex < sortItemCount; ++sortItemIndex) { PolygonSortData& sortData = sortingArray[sortItemIndex]; sortData.indices[0] = preparedIndices[sortItemIndex * polygonElementCount + 0]; sortData.indices[1] = preparedIndices[sortItemIndex * polygonElementCount + 1]; sortData.indices[2] = preparedIndices[sortItemIndex * polygonElementCount + 2]; } Vector<VegetationIndex>& indexData = renderData.GetIndices(); Vector<VegetationVertex>& vertexData = renderData.GetVertices(); currentResolutionIndexArray.push_back(Vector<VegetationSortedBufferItem>()); Vector<VegetationSortedBufferItem>& currentDirectionBuffers = currentResolutionIndexArray[indexBufferIndex]; uint32 sortDirectionCount = (uint32)directionPoints.size(); for(uint32 sortDirectionIndex = 0; sortDirectionIndex < sortDirectionCount; ++sortDirectionIndex) { Vector3 cameraPosition = directionPoints[sortDirectionIndex]; for(size_t sortItemIndex = 0; sortItemIndex < sortItemCount; ++sortItemIndex) { PolygonSortData& sortData = sortingArray[sortItemIndex]; sortData.cameraDistance = FLT_MAX; for(uint32 polygonIndex = 0; polygonIndex < polygonElementCount; ++polygonIndex) { float32 distance = (vertexData[sortData.indices[polygonIndex]].coord - cameraPosition).SquareLength(); if(distance < sortData.cameraDistance) { sortData.cameraDistance = distance; } } } std::stable_sort(sortingArray.begin(), sortingArray.end(), PolygonByDistanceCompareFunction); size_t prevIndexIndex = currentIndexIndex; for(size_t sortItemIndex = 0; sortItemIndex < sortItemCount; ++sortItemIndex) { PolygonSortData& sortData = sortingArray[sortItemIndex]; DVASSERT(currentIndexIndex < indexData.size()); indexData[currentIndexIndex] = sortData.indices[0]; currentIndexIndex++; indexData[currentIndexIndex] = sortData.indices[1]; currentIndexIndex++; indexData[currentIndexIndex] = sortData.indices[2]; currentIndexIndex++; } RenderDataObject* indexBuffer = new RenderDataObject(); indexBuffer->SetIndices(VEGETATION_INDEX_TYPE, (uint8*)(&indexData[prevIndexIndex]), (currentIndexIndex - prevIndexIndex)); VegetationSortedBufferItem sortedBufferItem; sortedBufferItem.SetRenderDataObject(indexBuffer); sortedBufferItem.sortDirection = indexBufferBBox.GetCenter() - cameraPosition; sortedBufferItem.sortDirection.Normalize(); SafeRelease(indexBuffer); currentDirectionBuffers.push_back(sortedBufferItem); } }