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);
		}
	}	
}
Esempio n. 4
0
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;
		}
	}
}
Esempio n. 5
0
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);
    }
}